home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
cwl2f-3.zip
/
FORM.DOC
< prev
next >
Wrap
Text File
|
1992-03-30
|
215KB
|
5,834 lines
@ME.FORMAT R
THE C DATA FORMS LIBRARY
(c) Copyright P. A. McKenzie 1990, 1991, 1992
All Rights Reserved
Version 1.0d
T A B L E O F C O N T E N T S
INPUT FORMS.................................................... 1
Form Manager .......................................... 1
INITIALIZING THE FORM LIBRARY ................................. 2
FormInitializeSystem() ................................ 2
FormInitializeFloat() ................................. 2
CREATING FIELD ENTRIES IN A FORM .............................. 3
The FIELD_ENTRY structure ..................................... 3
Field Types ........................................... 4
Field Row and Column .................................. 5
Field Mask ............................................ 6
Field Fill Character .................................. 6
Field Minimum Characters............................... 6
Field Maximum Width ................................... 6
Field Options ......................................... 6
Field Starting Input Position ......................... 9
Field Attributes ...................................... 9
Field Regular Expression .............................. 9
Alternate Methods of Creating FIELD_ENTRY's ........... 10
FormInitialize() .............................................. 13
Form Options .......................................... 13
Field Errors .......................................... 16
Setting Number of Decimal Places in a field with
FormSetFieldDecimal() ......................................... 16
SPECIAL DATA TYPES ............................................ 19
The LIST special field ................................ 19
Retrieving the list selection .................... 21
The TOGGLE special field .............................. 21
Retrieving the toggle selection .................. 23
The SUBFORM and VSUBFORM special fields ............... 23
BUTTON fields ......................................... 25
RADIO Fields and the RADIO_ENTRY structure ............ 30
Deactivating and Activating Radio Entries......... 32
Retrieving the Radio selection ................... 33
CHECKBOX Fields and the CHECKBOX_ENTRY structure ...... 34
Deactivating and Activating Checkbox Entries ..... 37
Retrieving the checkbox selection ................ 38
GETTING INPUT FROM A FORM ..................................... 40
FormGetInput() ........................................ 41
Virtual Form Scrolling ................................ 42
Editing Input ......................................... 42
Changing the Editing Key definitions globally using the
form_edit_key table ................................... 45
Page i The C Data Forms Library Page i
T A B L E O F C O N T E N T S
Changing the Editing Key definitions using
FormAssignFieldKeys() ................................. 45
Traversing fields and the FORM_HIGHLIGHT option ...... 47
ASSIGNING VALUES TO AND RETRIEVING VALUES FROM A FORM ......... 48
FormSetFieldVariable() ................................ 48
Placing input with FormPutFieldData() ................. 49
Retrieving Input with FormGetFieldData() .............. 50
Pre-filling a form with default data .................. 51
Setting up array of strings using Allocate2DArray() ... 51
Freeing a two dimensional array using Free2DArray() ... 53
Using FormInitializeFieldData() ....................... 53
SETTING FIELD OPTIONS ......................................... 56
FormSetFieldOptions() ................................. 56
SETTING FORM OPTIONS .......................................... 58
FormSetOptions() ...................................... 58
WRITING VALUES TO THE FIELD BUFFER ............................ 60
FormWriteFieldValue() ................................. 60
SETTING FIELD PRE-FUNCTIONS ................................... 61
Defining global pre-functions ......................... 61
Defining field specific pre-functions ................. 61
Return Values To The Form manager ..................... 62
SETTING FIELD POST-FUNCTIONS .................................. 66
Defining global post-functions ........................ 66
Defining field specific post-functions ................ 66
Return Values To The Form manager ..................... 66
UNDEFINED KEYSTROKE PROCESSING ................................ 69
form_undef_fkey_func and form_undef_akey_func
function pointers .................................. 69
Specifying when to call an undefined key function is a
Regular Expression ................................. 70
Return Values To The Form Manager ..................... 70
PROCESSING EDITING ERRORS ..................................... 73
Minimum Number of Characters Checking ................. 73
Overriding Error Checking for Minimum Number
of Characters ....................................... 73
Checking if Field Characters Match Regular Expression . 74
Calling a User Written Function when errors occur ..... 75
Return Values for User Written Function ............... 75
Page ii The C Data Forms Library Page ii
T A B L E O F C O N T E N T S
USER DEFINED ERROR CHECKING ................................... 78
FormSetFieldValidateFunction() ........................ 78
Return Values for the user defined error function ..... 78
FormCheckFieldRange() ................................. 80
CLEARING A FORM ............................................... 83
FormClear() ........................................... 83
EXITING A FORM ................................................ 84
FormSetExitFunction() ................................. 84
DISPOSING OF A FORM ........................................... 88
FormFree() ............................................ 88
MISCELLANEOUS FORM FUNCTIONS .................................. 89
FormGetFieldString() .................................. 89
FormGetFieldRowCol() .................................. 89
FORM MACROS ................................................... 90
Page iii The C Data Forms Library Page iii
INPUT FORMS
-----------
A data entry form can be defined as a collection of input fields
that are combined in a window. By using data entry forms, it makes
it easier to collect input. Without data entry forms, the only way
to get input is to call a series of WindowGet...() functions.
Although this is possible, it can be very cumbersome to manage
these fields if they are not in some way logically tied together,
even though each field is independent of each other. For example,
if you want to advance to the next field by using the down arrow
key on the keyboard, you would have to set up an undefined
keystroke function that tests for the down arrow, and then tell the
input manager to terminate the input. You would then tell your
program to advance to the next field and start the input process
over again for the new field.
By using forms, The C Data Forms library makes it much easier for
the programmer to set up a data entry form, without worrying about
the details of traversing from field to field, as the above example
has detailed.
The forms in The C Data Forms Library also allow other options.
Here are a few of them:
* You can have simple windowed forms or have forms that are larger
than the physical screen (virtual forms).
* You have pre and post functions on the field level as well as
the global level (pre-post function is called for all fields).
* Fields can have a user defined error function tied to them.
* Fields can be highlighted as the input cursor is moved from
field to field, or can remain the same color regardless of where
the input cursor is.
* Automatic conversion of a field to the right data type, and then
the converted value can be assigned to any variable you choose.
* Choice lists, toggle fields, subforms, radio, button, and
checkbox fields are supported.
* You can retrieve or update a field at any time, even when the
form is not the current input form.
The above are just some of the features of The C Data Forms
Library's form functions.
Form Manager
------------
The form manager is the set of functions internal in The C Data
Forms Library that handle the grunt work of processing a form.
Page 1 The C Data Forms Library Page 1
INITIALIZING THE FORM LIBRARY
-----------------------------
This section defines the preliminaries when setting up your program
to handle forms.
FormInitializeSystem()
----------------------
Before you call any form functions, you must call the
FormInitializeSystem() function. This function sets up global
variables used by the form manager. If this function is not
called, the form manager may act unpredictably, leading to
undesired effects. Here is the prototype:
void FormInitializeSystem(void)
There are no arguments or a return value. This function MUST be
called after WindowInitializeSystem() to take effect.
#include "cwlform.h" /* This include is needed for form
functions */
main()
{
WindowInitializeSystem();
FormInitializeSystem(); /* Note how FormInitializeSystem() is
called after
WindowInitializeSystem() */
}
FormInitializeFloat()
---------------------
If you are using any floating point values in your form i.e. double
and float data types, you must call the FormInitializeFloat()
function after you call FormInitializeSystem(). This function
allows the floating point library to be loaded into your program
when the program is linked. The C Data Forms Library will not use
any floating point functions unless FormInitializeFloat() is
called. Here is the prototype and a small example:
Prototype:
void FormInitializeFloat(void);
Example:
#include "cwlform.h"
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat(); /* Now C Data Forms knows to use
floating point routines */
}
Page 2 The C Data Forms Library Page 2
CREATING FIELD ENTRIES IN A FORM
--------------------------------
The FIELD_ENTRY structure
-------------------------
The most important thing to learn when creating a form is how to
set up the array of FIELD_ENTRY's. These FIELD_ENTRY's define
each field of the form, the field size, location, options, regular
expression, mask, minimum visible width of the field (this allows
left and right scrolling of long fields).
Here is the description of a FIELD_ENTRY structure:
int type -- This defines the fields data type (integer,
double, etc.)
unsigned row -- This defines the row in the window (or virtual
window) of where the field is located.
unsigned col -- This defines the column in the window (or
virtual window) of where the field is located.
char *mask -- This is the input mask to use for the field.
This mask is the same as the masks defined in the
WindowGet...() family of functions.
int fillchar -- This is the character to use for unfilled
input positions in the field.
int minchars -- This is the minimum number of characters to
accept in a field.
int maxwidth -- This is the visible width of the field. If
the input goes beyond the right edge of
the visible width of the field, the input
is scrolled.
unsigned long options -- These are the field options described for
the field.
int startpos -- This is the starting position in the field to
place the input cursor. Usually this is
position 1.
int attr -- Color attribute to use for the field.
char *regexp -- Regular expression used for the input field.
An array of these FIELD_ENTRY's is needed to build the form. The
order of the array elements determine the order of processing for
each field. Here is a simple way of creating an array of
FIELD_ENTRY's:
Page 3 The C Data Forms Library Page 3
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
FIELD_ENTRY field_array[] =
/* define first field entry */
{INTEGER, /* field type */
1, /* field row in window (or virtual window) */
20, /* field column in window (or virtual window) */
"___", /* field mask */
'_', /* fill character to use */
1, /* minimum characters to accept */
3, /* maximum field width */
FIELD_RJUSTIFY, /* field option to use */
1, /* starting position */
NORM, /* field attribute */
"3[0-9]", /* regular expression to use */
/* Now define other field entries */
STRING, 2, 20, "__________", '_', 0, 10, NO_FIELD_OPTIONS,1,NORM,
"10.",
INTEGER,3, 20, "__", '_', 2, 2, NO_FIELD_OPTIONS, 1,NORM,
"2[0-9]",
DOUBLE,4, 20, "_______",'_',1,7, FIELD_COMMA | FIELD_LJUSTIFY,1,
NORM,"7[0-9/.]", CHAR, 5, 20, "_", '_', 1, 1,
FIELD_UPPERCASE, 1,NORM, "[YyNn]",
/* Now terminate the field array */
FIELDEND};
Note that "cwlform.h" includes "window.h", so there is no need to
include window.h.
The above example creates an array of FIELD_ENTRY's called
field_array. There are five field entries in the field_array
array. Note that the array is terminated with a FIELDEND field
type. The above method of initializing an array of FIELD_ENTRY's
globally is just one way to create the array of FIELD_ENTRY's.
There are other ways of creating an array of FIELD_ENTRY's by
making use of function calls. These methods will be discussed
later.
Field Types
-----------
The first member in the first entry is the constant INTEGER. This
denotes the type of the data that will be entered in this field.
This also tells the form manager what type of conversion will be
required when converting the input. When the user enters the
input, the input is in string form, so conversion is necessary. A
list of the constants used here and their definitions is as
follows:
Page 4 The C Data Forms Library Page 4
Integer data types:
C language
Constant data type
-------- ----------
INTEGER int
UINTEGER unsigned int
LINTEGER long
ULINTEGER unsigned long
CHAR char
String data types:
C language
Constant data type
-------- ------------
STRING char array[]
Floating point data types:
C language
Constant data type
-------- ----------
DOUBLE double
FLOAT float
Special data type:
Constant
--------
FIELDEND
LIST
SUBFORM
VSUBFORM
TOGGLE
RADIO
CHECKBOX
BUTTON
The special data type FIELDEND is used to terminate the array of
fields. You MUST use this constant as the last field type, or the
form manager will not know where the last field is. The other
special data types will be discussed later in this section.
Field Row and Column
--------------------
The second and third members of the first entry is the row and
column position number of where to place the field. Remember that
this position can either be in a window or a virtual window.
Page 5 The C Data Forms Library Page 5
Field Mask
----------
The fourth member is the field mask to use for the field. This
mask follows the same rules as input masks for the
WindowGetMask...() family of functions. The maximum number of
characters in a mask string is 255 characters. This includes
input and non-input positions in the mask. If you want to
increase this number, you will have to change the constant
MAXFIELDSIZE defined in cwlform.h to whatever number you desire
plus 1 (the extra character is for the null terminator). Then you
must recompile The C Data Forms Library using this new value.
Field Fill Character
--------------------
The fifth member is the fill character to use for empty input
positions in the field. In our example the fill character is the
underscore ('_').
Field Minimum Characters
------------------------
The sixth member is the minimum number of characters to accept for
this field. Our example says you must enter at least 1 character
in the first field. You can override the field minimum by using
the FIELD_OVERRIDE_FORWARD and the FIELD_OVERRIDE_BACKWARD field
options defined below.
Field Maximum Width
-------------------
The seventh member tells us the maximum visible width of the
field. Our example shows that the visible width should be 3
characters.
Field Options
-------------
The eighth member are the field options used on the field. Here
are a list of the field options available:
FIELD_UPPERCASE - Characters entered in the field are
automatically converted to upper case if lower
case characters are entered.
FIELD_LOWERCASE - Characters entered in the field are
automatically converted to lower case if upper
case characters are entered.
Page 6 The C Data Forms Library Page 6
FIELD_ENHANCEDKEY - Field can recognize and distinguish between extra
keys on extended keyboard (i.e. F11, F12,
dedicated cursor keys, etc.) and the normal
keys.
FIELD_CHECKREGEXP - Each character in the field will be checked
against the field's regular expression. This
check is done when the user wants to accept
the input.
FIELD_CHECKSPACES - Spaces will be counted as valid characters
when the form manager checks if the minimum
number of characters has been entered.
FIELD_AUTORETURN - The field is automatically accepted when the
last input position is filled with a character.
FIELD_CHECKREGEXP_IGNORECASE - Same as FIELD_CHECKREGEXP except
that case is ignored for
alphabetic characters.
FIELD_FLUSHBUFFER - Keyboard is flushed before entering the field.
This will override whatever the
FLUSH_KEYBOARD() macro is set to.
FIELD_HOMECURSOR - Input field will be scrolled back to the first
character when the field is accepted. This is
good for fields that have scrolled to the
right.
FIELD_PROTECT - The input field will not be edited. It will be
skipped over by the form manager.
FIELD_COMMA - This option is only used for numeric field types
(INTEGER, UINTEGER, LONG, ULONG, DOUBLE and FLOAT
types). Commas are placed in the input when it is
accepted. While inputting in the field, the form
manager deletes the commas. To make sure that the
comma formatted string will fit in the field, the
field maximum width should be at least as long as
the comma formatted number.
FIELD_LJUSTIFY - The input field will be left justified when it is
accepted.
FIELD_RJUSTIFY - The input field will be right justified when it
is accepted.
FIELD_ZSUPPRESS1 - This option is used only for numeric field
types. The input will suppress all leading
zeros when the field is accepted.
Page 7 The C Data Forms Library Page 7
FIELD_ZSUPPRESS2 - This option does the same as FIELD_ZSUPPRESS1
except that if the string entered is all zeros,
leading zeros except for the last zero is
suppressed. For example, if the user enters
"00000" the resulting string after suppressing
will be "0".
FIELD_PASSWORD - This is a password field. When inputting into this
field, only the password character (default is
the asterisk '*') is displayed.
FIELD_CLEARFIELD - Clears the input field if the first key pressed
is recognized by the regular expression as a
valid input key. If a cursor movement key is
pressed first, the field is not cleared if any
subsequent input keys are pressed.
FIELD_CHECK - When this option is chosen the field is checked to
make sure that the minimum number of characters
have been entered when the user wants to exit the
form.
FIELD_OVERRIDE_FORWARD - You can go to the next field (go toward
the last field) from the input field
without checking to see if the minimum
number of characters has been entered.
However, you cannot go to a previous
field (go toward the first field) if the
minimum number of characters is not met.
FIELD_OVERRIDE_BACKWARD - Same as FIELD_OVERRIDE_FORWARD except
that you cannot go forward (toward the
last input field) without meeting the
requirements of entering the minimum
number of characters expected.
NO_FIELD_OPTIONS - The above options described are turned
off.
You can combine options with a bitwise OR (|). For example, if
you want a numeric field zero suppressed, comma formatted, and
left justified you would do the following:
FIELD_ZSUPPRESS1 | FIELD_COMMA | FIELD_LJUSTIFY
If both FIELD_ZSUPPRESS1 and FIELD_ZSUPPRESS2 are used as options,
FIELD_ZSUPPRESS1 overrides FIELD_ZSUPPRESS2.
FIELD_LJUSTIFY overrides FIELD_RJUSTIFY if both options are
chosen.
If both FIELD_OVERRIDE_FORWARD and FIELD_OVERRIDE_BACKWARD are
chosen, you can exit a field in any direction without checking the
regular expression.
NO_FIELD_OPTIONS must not be combined with any other options.
Page 8 The C Data Forms Library Page 8
You can also turn off and turn on field options at run time and
during processing of a form by using the FormSetFieldOptions()
function defined later in the manual.
Field Starting Input Position
-----------------------------
This value tells the form manager where to place the cursor when
input is started. The position numbers range from 1 to the
highest field position in the input field. Usually the starting
position for the field is 1, but you can start the input anywhere
in a field.
Field Attributes
----------------
The tenth member of the FIELD_ENTRY structure is the field
attribute. This attribute will be the color of the field
characters that are inputted. Note that in the example above, the
constants BLACK_ and WHITE_ are used instead of the usual lower
case global variables, black and white. This is done because the
lower case color variables do not have a value until
WindowInitializeSystem() is called, while the capitalized
constants have a value that is predefined. We need to use the
predefined constants because we are initializing an array outside
of the main() function.
Field Regular Expression
------------------------
The last member of the FIELD_ENTRY is the regular expression to
use. It is wise to use the proper regular expression for a given
field type. For example, use a [0-9] type regular expression for
integer data. Here are a list of sample regular expressions to
use for a given data type:
Constant Simple Reg.
Data Type Expression
--------- ----------
INTEGER or LINTEGER [0-9], [0-9/-+]
UINTEGER or ULINTEGER [0-9]
STRING Any regular expression.
CHAR Any one character regular
expression.
DOUBLE or FLOAT [0-9], [0-9/-+], [0-9/.], [0-9/.eE]
Page 9 The C Data Forms Library Page 9
Except for the CHAR data type, you can use multiplying factors or
complex regular expressions composed of the above regular
expressions. The regular expressions defined above are just
examples of what you should use.
The total length of the number of characters in the regular
expression must not exceed the maximum number of characters in a
field. The current maximum number of characters allowed in a
field is 255. If you want to change this, you must modify the
source code and change the constant MAXFIELDSIZE to whatever value
you choose. Of course, you would have to recompile the source
code.
Alternate Methods of Creating FIELD_ENTRY's
------------------------------------------
Another method of creating the FIELD_ENTRY's is to create them
dynamically. Here is an example:
#include "cwlform.h"
#define NUMFIELDS 5
#define NORM CREATE_VIDEO_ATTRIBUTE(black,white)
FIELD_ENTRY_PTR field_array; /* Notice that we have a pointer to
what will be an array of
FIELD_ENTRY's */
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
/* Initialize with at least number of total fields */
field_array = FieldAllocate(NUMFIELDS);
/* Call function to create fields in field_array sequentially */
FieldCreate(field_array, /* FIELD_ENTRY pointer */
1, /* field number */
/* The rest of the arguments are just like the first example */
INTEGER, /* field type */
1, /* field row */
20, /* field column */
"___", /* field mask */
'_', /* fill character */
1, /* minimum characters */
3, /* maximum field width */
FIELD_RJUSTIFY, /* field options */
1, /* starting position */
NORM, /* attribute */
"3[0-9]"); /* regular expression */
FieldCreate(field_array,2,STRING,2,20,"__________",'_',0,10,
NO_FIELD_OPTIONS,1,NORM,"10.");
Page 10 The C Data Forms Library Page 10
FieldCreate(field_array,3,INTEGER,3,20,"__",'_',2,2,
NO_FIELD_OPTIONS,1,NORM,"2[0-9]");
FieldCreate(field_array,4,DOUBLE,4,20, "_______",'_',1,7,
FIELD_COMMA | FIELD_LJUSTIFY,1,NORM,"7[0-9/.]");
FieldCreate(field_array,5,CHAR,5,20,"_",'_',1,1,
FIELD_UPPERCASE,1,NORM,"[YyNn]");
/* Terminate fields with FieldEnd */
FieldEnd(field_array,NUMFIELDS);
/*
some other stuff
*/
/* Dispose of Field entries created */
FieldDeallocate(field_array);
}
The difference between the above method and the method used to
globally initialize an array are the following:
1) The variable type for field_array is FIELD_ENTRY_PTR, not
FIELD_ENTRY as the previous examples so far have illustrated.
2) You must call the FieldAllocate() function to allocate space
for the number of fields desired. If you do not call field
allocate, you will surely get a memory overwrite error. The
return value to FieldAllocate() must be assigned to a
FIELD_ENTRY_PTR, as the above example shows.
The array of fields are allocated from the heap at runtime, as
opposed to the static method which sets up the memory scheme at
link time.
3) The next thing you must do is to fill in the field information
by calling the FieldCreate() function. The first argument to the
FieldCreate() function is the FIELD_ENTRY_PTR. The second
argument is the field number to assign this information to. The
rest of the arguments are the same order as the first example i.e.
field type, row, column, mask, etc. FieldCreate() is called for
each field desired.
4) The FieldEnd() function must be called to terminate the list of
fields. The first argument is the FIELD_ENTRY_PTR, and the second
argument is the total number of fields defined.
5) After you have called FormFree() (discussed later) and no
longer need the array of fields anymore, you should call
FieldDeallocate() to free the memory assigned to the array of
fields. The only argument to FieldDeallocate() is the
FIELD_ENTRY_PTR.
Page 11 The C Data Forms Library Page 11
All of these functions except for FieldAllocate() have no return
values. The FieldAllocate() function returns a FIELD_ENTRY_PTR if
successful, and a FIELD_ENTRY_NULL_PTR if unsuccessful.
The advantages of using the above method over the first method is
that FIELD_ENTRY's are dynamically allocated rather than
statically declared at compile time. This allows the programmer
to create loops to set up fields, read field information from a
file and assign this info to a FIELD_ENTRY, etc.
The disadvantages of this method is that you have to call several
functions to accomplish creating an array of fields, while the
static method does not call any functions. Function overhead is
saved in the static method.
Here is another method of using statically defined data and
function calls:
#include "cwlform.h"
#define NUMFIELDS 5
#define NORM CREATE_VIDEO_ATTRIBUTE(black,white)
FIELD_ENTRY field_array[NUMFIELDS+1]; /* Notice that we have an
array of FIELD_ENTRY's. 1
is added for FIELDEND
entry */
main()
{
WindowInitializeSystem();
FormInitializeSystem();
/* Call function to create fields in field_array sequentially */
FieldCreate(field_array,1,INTEGER,1,20,"___",'_',1,3,
FIELD_RJUSTIFY,1,NORM,"3[0-9]");
FieldCreate(field_array,2,STRING,2,20,"__________",'_',0,10,
NO_FIELD_OPTIONS,1,NORM,"10.");
FieldCreate(field_array,3,INTEGER,3,20,"__",'_',2,2,
NO_FIELD_OPTIONS,1,NORM,"2[0-9]");
FieldCreate(field_array,4,DOUBLE,4,20, "_______",'_',1,7,
FIELD_COMMA | FIELD_LJUSTIFY,1,NORM,"7[0-9/.]");
FieldCreate(field_array,5,CHAR,5,20,"_",'_',1,1,FIELD_UPPERCASE,
1,NORM,"[YyNn]");
/* Terminate fields with FieldEnd */
FieldEnd(field_array,NUMFIELDS);
}
Page 12 The C Data Forms Library Page 12
The above method declares an array of FIELD_ENTRY's, but does not
initialize them in the same way as the first method. Note that
there is no function call to FieldAllocate() or FieldDeallocate()
since the array of fields, field_array, was already declared with
6 elements (NUMFIELDS + 1). All other aspects of this method is
the same as the second method.
This method statically declares an array but does have to allocate
any memory from the heap.
From this point on, this manual will use the first method
discussed on page 2 when code fragments are written.
FormInitialize() function
-------------------------
The next step is to take the array of FIELD_ENTRY's and assign
them to a window. The FormInitialize() does just this.
A prototype of this function is as follows:
FORMPTR FormInitialize(void *window, FIELD_ENTRY *field_entry,
int form_options)
Note that this function returns a pointer to a structure. This
pointer is called a FORMPTR. You must assign the return value to
a variable declared as a FORMPTR.
The first argument to FormInitialize() seems strange. The reason
for the void pointer instead of the usual WPOINTER or VWPOINTER is
that either WPOINTER or VWPOINTER can be used as the first
argument. As was stated before, forms can either be window based
or virtual window based.
If the first argument is a WPOINTER, the window must be
initialized and opened before calling FormInitialize(). If the
first argument is a VWPOINTER, the virtual window must be
initialized with VirtualInitialize() and must be an attributed
virtual window (VirtualInitialize() must be called with ATTRIBUTE
as the first argument).
The second argument is the array of FIELD_ENTRY's.
The third argument are the form options. A list of the form
options are as follows:
Form Option
-----------
FORM_WRAP - form manager will move the input cursor to the
first input field if the last input field is
accepted, and will move the input cursor to the
last input field if the cursor goes beyond the
first field.
Page 13 The C Data Forms Library Page 13
FORM_CHECK - When this option is on, all fields are checked on
exit of the form to see if they satisfy the
minimum number of characters.
FORM_EXIT_INITIAL - This option allows exiting a form if an
attempt is made to move the input cursor above
the first input field in the form.
FORM_NOEXIT_LAST - When this option is on, the form is not exited
when the last field is accepted.
FORM_HIGHLIGHT - When this option is on, each field takes on its
field color only when it is being inputted. When
a field is not being inputted, the color of the
field is the text color of the window.
When this option is off, all fields take on their
color regardless if the field is currently being
inputted.
FORM_VIRTUAL - You must use this option if the first argument to
FormInitialize() is a VWPOINTER.
FORM_STATIC - The form window will not be hidden when the form
is exited.
NO_FORM_OPTIONS - All options described above are turned off.
You can combine form options using the bitwise OR (|). Form
options can be turned off or on any time using the
FormSetOptions() function defined later in the manual.
Example:
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
WPOINTER w;
VWPOINTER vw;
FORMPTR form, /* pointers to FORM's */
form2;
FIELD_ENTRY field_array[] =
{INTEGER,1,20,"___",'_',1,3,FIELD_RJUSTIFY,NORM,"3[0-9]",
STRING, 2, 20, "__________", '_', 0, 10,NO_FIELD_OPTIONS,
1,NORM, "10.",
INTEGER,3, 20, "__", '_', 2, 2,NO_FIELD_OPTIONS, 1,NORM,
"2[0-9]",
DOUBLE,4, 20,"_______",'_',1,7,FIELD_COMMA|FIELD_LJUSTIFY,
1,NORM,"7[0-9/.]",
CHAR, 5, 20, "_", '_', 1, 1, FIELD_UPPERCASE, 1,NORM,
"[YyNn]",
FIELDEND };
Page 14 The C Data Forms Library Page 14
main()
{
WindowInitializeSystem();
WindowSaveInitial(0);
FormInitializeSystem();
FormInitializeFloat();
w = WindowInitialize(BORDER,1,1,40,10,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* vw must be ATTRIBUTEd if we want to use it as a form */
vw = VirtualInitialize(ATTRIBUTE,10,80,NORM);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
NO_FORM_OPTIONS); /* form options */
if (form == FORM_NULL_PTR)
{
printf("Form could not be initialized");
exit(0);
}
/* Initialize with VWPOINTER */
form2 = FormInitialize(vw, field_array, FORM_VIRTUAL);
{
printf("Form could not be initialized");
exit(0);
}
}
Note that when initializing with a virtual window, the option
FORM_VIRTUAL must be used as a form option.
FormInitialize() returns a valid FORMPTR if successful. If there
is an error, a FORM_NULL_PTR (null FORMPTR) is returned, and
window_error_code is set to one of the following:
NO_FIELDS_DEFINED if there are no fields in the FIELD_ENTRY array.
NO_HEAP_MEM if there is not enough memory to allocate for the form
and any internal field buffers.
NO_INPUT_CHARS if a field mask contains no characters.
INVALID_NUM_CHARS if the number of characters denoted by a field's
regular expression does not equal the number of input positions in
the field mask.
BAD_WINDOW if the window does not exist.
WINDOW_NOT_OPEN if the window is not open for writing.
BAD_V_WINDOW if the virtual window specified does not exist.
FIELD_RANGE_ERROR if there is a field that is out of bounds of the
dimensions of the window or the virtual window.
Page 15 The C Data Forms Library Page 15
Field Errors
------------
If there is an error with a particular field, the global variable
field_bad_number tells which field is the offending field. Field
numbers are numbered from 1 to the highest field in the array of
fields.
Here is how a complete form error checking function routine would
look like:
#include "cwlform.h"
#include <stdio.h>
FIELD_ENTRY field_array[] = { /* ... Initialize fields ... */ }
VWPOINTER vw;
WPOINTER w;
FORMPTR form;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,40,10,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* vw must be ATTRIBUTEd if we want to use it as a form */
vw = VirtualInitialize(ATTRIBUTE,10,80,NORM);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
NO_FORM_OPTIONS); /* form options */
if (form == FORM_NULL_PTR)
write_form_error(1);
/* Initialize with VWPOINTER */
form2 = FormInitialize(vw, field_array, FORM_VIRTUAL);
if (form2 == FORM_NULL_PTR)
write_form_error(2);
}
void write_form_error(int formnum)
{
switch (window_error_code)
{
case NO_FIELDS_DEFINED:
printf("Form %d has no fields",formnum);
break;
case NO_HEAP_MEM:
printf("Not enough heap memory to allocate for form %d",
formnum);
break;
Page 16 The C Data Forms Library Page 16
case NO_INPUT_CHARS:
printf ("Field %d has an invalid mask in form %d",
field_bad_number, formnum);
break;
case TOO_MANY_CHARS:
printf("Field %d has too many input characters in form %d",
field_bad_number, formnum);
break;
case BAD_WINDOW:
printf("Window or virtual window does not exist for form %d",
formnum);
break;
case WINDOW_NOT_OPEN:
printf("Window not open for form %d",formnum);
break;
case BAD_V_WINDOW:
printf("Virtual window does not exist for form %d",
formnum);
break;
case FIELD_RANGE_ERROR:
printf("Field %d is out of bounds in form %d",
field_bad_number,formnum);
break;
default:
printf("Undefined error for form %d",formnum);
break;
}
exit(0);
}
The above function write_error_form() processes any error that may
occur when initializing a form.
Setting Number of Decimal Places in a field with
FormSetFieldDecimal()
---------------------
If the field type is FLOAT or DOUBLE, the form manager should be
informed of the number of decimal places in the field. The
FormSetFieldDecimal() function tells the form manager the number of
decimal places in a field. Here is the prototype:
int FormSetFieldDecimal(FORMPTR form, int entry, int numdec)
Page 17 The C Data Forms Library Page 17
The first two arguments are the form and entry number,
respectively, and the last argument is the number of decimal
places. If the FormSetFieldDecimal() function is not called, the
form manager will assume 0 decimal places. The form manager will
round off any number that is inputted to the desired decimal
places.
If there are no errors, FormSetFieldDecimal() returns NO_ERROR.
If there are errors, FormSetFieldDecimal() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Page 18 The C Data Forms Library Page 18
SPECIAL DATA TYPES
------------------
In the previous section, there was a very brief discussion of the
special data types, namely LIST, TOGGLE, SUBFORM, VSUBFORM, BUTTON,
RADIO, and CHECKBOX. These special data types are very useful if
the information to be entered for a field is not a normal text
field. For example, LIST allows you to use a popup list of choices
to be displayed, TOGGLE allows you to toggle between choices, and
SUBFORM and VSUBFORM allows you to enter a subform for a field.
The BUTTON field is a no input field, but powerful in what it can
do. BUTTON fields can close forms, go to previous fields, or can
have a user defined definition if the user 'accepts' the field.
The RADIO field implements a radio button field, and CHECKBOX
implements a check box type field. A discussion of radio and check
box fields will be discussed below.
For all of the special fields, the field type specified when the
fields on the form was initialized must match with the desired
special field for the field entry.
The LIST special field
----------------------
If a field type is LIST, the form manager will display a pop-up
menu of choices. Once the selection is made, the string in the
pop-up menu is written to the field. The field should be big
enough to hold the longest string in the pop-up menu. Where does
the form get the pop-up menu from? You create the pop-up menu
just like any normal popup menu. If you are not familiar with
creating pop-up menus, please refer to the documentation included
with The C Window Library.
To let the form know about the pop-up menu, you must call the
FormSetListField() function. This function lets the form know the
address of the pop-up menu pointer (POPUP_MENU_PTR). Here is the
prototype:
int FormSetListField(FORMPTR form, int entry, int rank,
int start, POPUP_MENU_PTR pop)
The first argument is the pointer to the form. The second
argument is the form entry to assign the POPUP_MENU_PTR to. THe
third argument is the rank of the popup window. The fourth
argument is the starting entry to place the highlight on. Entry
numbers are numbered from 1 to the highest entry. The last
argument is the POPUP_MENU_PTR itself.
The form must be initialized with FormInitialize(), the entry
number must exist and must have been defined as a LIST field, and
the POPUP_MENU_PTR must also have been created before calling
FormSetListField(). If any of these criteria are violated, an
error is returned. Here is an example:
#include "cwlform.h"
#include "menu.h"
Page 19 The C Data Forms Library Page 19
FIELD_ENTRY fentry[] = {LIST,9,15,"________",' ',0,8,
NO_FIELD_OPTIONS,1,REVERSE,"8.",
FIELDEND};
FORMPTR form;
POPUP_MENU_ENTRY popup_entry[] = {"Choice 1",1,0,0,NULLFN,
"Choice 2",2,0,0,NULLFN,
"Choice 3",3,0,0,NULLFN,
"Choice 4",4,0,0,NULLFN,
CWL_NULL,0};
POPUP_MENU_PTR popup;
unsigned menu_colors[NUMPOPUPCOLORS];
WPOINTER w;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
/* set up menu colors */
menu_colors[ENTRYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[BORDERCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[HOTKEYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,blue);
menu_colors[HIGHLIGHTCOLOR] = CREATE_VIDEO_ATTRIBUTE(cyan,black);
menu_colors[UNAVAILCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* create popup menu */
popup = PopupCreateMenu(popup_entry,menu_colors,4,10,7,
NO_POPUP_OPTIONS,WNULLFN,VWNULLFN);
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT);
/* Let form know about popup menu */
FormSetListField(form,1,1,1,popup);
/* get the input */
FormGetInput(form,1,1);
}
If you take a look at the array of FIELD_ENTRY's, the first field
type is a LIST field. This informs the form manager that the
first field will have a pop-up list associated with it.
Also note that The POPUP_MENU_ENTRY's menu function is a NULLFN.
The C Data Forms Library automatically assigns an internal
function to the pop-up menu when FormSetListField() is called,
which will supersede any function that you may have assigned to
the menu entry.
When FormSetListField() is called, the FORMPTR is assigned the
POPUP_MENU_PTR, and any menu function is overridden by the C Data
Forms function.
Page 20 The C Data Forms Library Page 20
With a pop-up list, you can have hotkeys, secondary hotkeys,
pre-functions, mouse support, etc. just like pop-up menus. The
only limit is that the function to perform when a selection is
made is a Data Forms internal function, and not the function that
you may have assigned to it previously.
If there are no errors, FormSetListField() returns NO_ERROR.
If there are errors, FormSetListField() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to create the data
structure required for a LIST field.
Retrieving the LIST selection
-----------------------------
To inspect the choice that was selected, use the
FormGetListChoice() function. Here is the prototype:
int FormGetListChoice(FORMPTR form, int entry)
The only two arguments are the form and entry number of the LIST
field. If successful, FormGetListChoice() returns an integer
denoting the LIST entry that was selected. Entry numbers are
numbered from 1 to the highest entry in the list, and are numbered
in the order that was specified in the pop-up menu.
If the LIST field is protected, FormGetListChoice() returns 0.
If there are errors, FormGetListChoice() returns one of the
following:
UNDEFINED_FORM if the form does not exist.
UNDEFINED_FIELD if the field does not exist, or the field is not a
LIST field.
The TOGGLE special field
------------------------
The TOGGLE field allows you to make selections by pressing the
space bar (default) to cycle through selections. You can also
accomplish the same thing with a LIST field, with a one-line
borderless pop-up window. However, TOGGLE fields are much easier
to use. To let the FORMPTR know that a field is a toggle field,
the FIELD_ENTRY field type must have a TOGGLE type, and you must
call the FormSetToggleField() function to assign the pointer to
the TOGGLE list.
Page 21 The C Data Forms Library Page 21
Here is a small example that creates a TOGGLE list:
char *toglist[] = {"ITEM1", "ITEM2", "ITEM3", TOGGLE_NULL};
In other words, the TOGGLE list is just an array of character
strings, with the last character string being the TOGGLE_NULL
constant. You MUST have the TOGGLE_NULL constant to terminate the
array of string, or else the form manager will not know where the
TOGGLE list ends. Of course this is only one of many ways to
create and initialize an array of character strings.
The prototype to the FormSetToggleField() is as follows:
int FormSetToggleField(FORMPTR form, int entry, char **toglist)
The first argument is the pointer to the form. The second
argument is the form entry to assign the toggle array to, and the
third argument is the toggle character array. The form must be
initialized with FormInitialize(), the entry number must exist and
must have been defined as a TOGGLE field.
Here is an example:
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
FIELD_ENTRY fentry[] = {TOGGLE,1,1,"________",' ',0,8,
NO_FIELD_OPTIONS,1,REVERSE,"8.",FIELDEND};
FORMPTR form;
char *tog[] = {"Choice 1","Choice 2","Choice 3","Choice 4",
TOGGLE_NULL};
WPOINTER w;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT|FORM_STATIC);
/* Let form know about toggle field */
FormSetToggleField(form,1,tog);
/* get the input */
FormGetInput(form,1,1);
WindowMoveCursor(w,3,1);
/* get the choice */
WindowPrintf(w,"The choice that was made was %d",
FormGetToggleChoice(form,1));
}
Page 22 The C Data Forms Library Page 22
By default, the toggle key is the space bar, but this can be
changed by changing the field key definitions. This will be
discussed later in subsequent sections.
If there are no errors, FormSetToggleField() returns NO_ERROR.
If there are errors, FormSetToggleField() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Retrieving the toggle selection
-------------------------------
To get the selection that was made in a toggle field, use the
FormGetToggleChoice() function. This function returns the toggle
entry that was selected. Entries are numbered from 1 to the
highest entry in the toggle field. Here is the prototype:
int FormGetToggleChoice(FORMPTR form, int entry)
The arguments are the form and entry number of the toggle field.
FormGetToggleChoice() returns 0 if the toggle field is a protected
field.
If there are errors, FormGetToggleChoice() returns one of the
following:
UNDEFINED_FORM if the form does not exist.
UNDEFINED_FIELD if the field does not exist, or the field is not a
TOGGLE field.
SUBFORM and VSUBFORM special fields
-----------------------------------
You can define a field in a form as another form. When the field
that is defined as a subform is entered, the form manager
processes the subform. When the subform is completed, the form
manager returns control to the next field entry in the form that
called the subform. Subforms can contain other subforms, so there
is no theoretical limit to the nesting level for subforms. If you
have deeply nested subforms, make sure that you have enough stack
space when compiling and linking your programs.
The only difference between SUBFORM and VSUBFORM is that VSUBFORM
informs the form manager that the subform is a virtual (scrolling)
form.
Page 23 The C Data Forms Library Page 23
The way to define a field as a SUBFORM or VSUBFORM is to make sure
the field type for the FIELD_ENTRY is SUBFORM (VSUBFORM). Setting
up a subform is EXACTLY the same way as you would set up a regular
form. THERE IS NO DIFFERENCE! Once your subform is set up, you
must call the FormSetSubformField() for SUBFORMS, or
FormSetVSubformField() for VSUBFORMS. Here are the prototypes:
FormSetSubformField(FORMPTR form, int entry, int rank,
int start, FORMPTR subform)
FormSetVSubformField(FORMPTR form, int entry, int rank,
int start, FORMPTR vsubform, WPOINTER viewport)
The only difference between the two functions is that
FormSetVSubformField() allows you to specify the viewport that the
virtual form will be displayed on. You must supply this argument
if you want the virtual subform to work correctly.
The first argument is the form to assign the subform to. The
second argument is the entry in the form that will be a subform
field. The third argument is the rank of the subform window.
The fourth argument is the starting entry in the subform to
begin getting input. The fifth argument is the pointer to
the subform itself. The last argument in FormSetVSubformField()
is the viewport window. All of the above must exist, or an error
will be returned. Here is an example:
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
/* initialize entries for form 1 */
FIELD_ENTRY fentry[] = {INTEGER,1,1,"________",' ',0,8,
NO_FIELD_OPTIONS,1,REVERSE,"8.",
SUBFORM,0,0,"",' ',0,0,NO_FIELD_OPTIONS,
0,0,"",FIELDEND};
/* initialize entries for subform */
FIELD_ENTRY fentry2[] =
{INTEGER,1,1,"____",' ',0,4,NO_FIELD_OPTIONS,1, REVERSE,"4.",
FIELDEND};
FORMPTR form,subform;
WPOINTER w,w2;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
w2 = WindowInitialize(BORDER,6,10,50,12,NORM,NORM,SINGLEBOX);
WindowOpen(w2);
Page 24 The C Data Forms Library Page 24
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT);
subform = FormInitialize(w2,fentry2,FORM_HIGHLIGHT);
/* Let form know about subform field */
FormSetSubformField(form,2,1,1,subform);
/* get the input */
FormGetInput(form,1,1);
}
Note that a SUBFORM (VSUBFORM) FIELD_ENTRY's only important parts
are the field type, and options. The mask, attribute, regular
expression, start position, row, col, etc. are irrelevant since
the field is a whole form. This is why the SUBFORM field entry has
bogus (don't care) arguments for these items.
If there are no errors, FormSetSubformField() and
FormSetVSubformField() return NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR or subform FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
BUTTON fields
-------------
A button field is a field that does not accept input but does
certain actions when selected. These actions can be anything from
closing a form to doing a user-defined function. When the button
field is accepted, the action tied to the button field is done. If
the user wants to skip over the button field, he/she would hit a
previous field or next field key. These key definitions are
discussed in the GETTING INPUT FROM A FORM section.
To inform the form manager that a field is a button field, you must
first set the field type to BUTTON. Field types are set when
defining the array of field entries. After the field entries have
been defined, the next step is to use the FormSetButtonField()
function. Here is the prototype to this function:
int FormSetButtonField(FORMPTR form, int entry, int retval,
char *text, int *attr,
int (*button_func)(FORMPTR f, int e,
int *new_entry))
The first argument is the form to set the button field.
The second argument is the entry in the form to set as the button
field.
Page 25 The C Data Forms Library Page 25
The third argument is the value that will be returned to the form
manager if the button field is accepted. The possible return
values and their descriptions will be discussed later.
The fourth argument is a string that is written to the form window.
This string will be placed in the (row,col) coordinates specified
when the field was defined. This string should contain useful
information to the user as to what the button will do if it is
accepted. For example, the string "Close" can be written to the
form window if accepting the button will close the form. This
string is also highlighted when the button field is the current
field. If the FORM_HIGHLIGHT option is on, the button field is
only highlighted when it is the current field.
The fifth argument is an array of attributes that will be used for
highlighting the button field if it is the active field, and
lowlighting if it is not the active field. The positions in this
array denote the following colors:
NORMATTR - This is the color of the unhighlighted button field.
HIATTR - This is the color of the highlighted button.
For instance:
int myattr[2];
/* ... */
myattr[NORMATTR] = CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_);
myattr[HIATTR] = CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_);
The last argument is a pointer to a user-defined function that will
return a value to the form manager. The possible return values
will be discussed later. The user-defined function takes three
arguments. The first argument is a pointer to the form that called
your user-defined function, and the second argument is the entry in
the form that called your user-defined function. The third
argument is a pointer to an integer that will denote a field number
to change to if the FIELD_NEWFIELD value is returned to the form
manager. The FIELD_NEWFIELD value will be discussed below.
An advantage of using a user-defined function is that the return
value to the form manager can be dynamic. In other words, your
user-defined function controls what value is returned to the form
manager. You may have different return values that you want to
implement depending on the state of the form, what input has been
entered in previous fields, etc. This user-defined function is not
limited. You can do just about anything in this function,
including opening other forms, displaying windows, etc.
The user-defined function MUST return a value to the form manager.
If not, unpredictable things may happen in the processing of the
forms.
If no user-defined function is desired, use the NO_BUTTON_FUNC
macro in place of the function pointer in the last argument in
FormSetButtonField(). The button field will just return the
value assigned to it if NO_BUTTON_FUNC is used. For example:
Page 26 The C Data Forms Library Page 26
FormSetButtonField(form,entry,FORM_EXIT,"String",NO_BUTTON_FUNC)
will return FORM_EXIT if the button field is accepted.
If you do have a user-defined function, the normal return value,
i.e. the third argument in FormSetButtonField() is ignored, and the
return value for the user-defined function is used.
Here are the possible return values that a button field can return
to the form manager. These return values are also used for the
user-defined function (if it exists) that is bound to the button.
Return Value Definition
------------ ----------
FIELD_PREVFIELD Move input cursor to the previous field
in the form and start editing from there.
FIELD_NEXTFIELD Move input cursor to the next field in
the form and continue editing the next
field.
FIELD_CONTINUE_PROCESS Do nothing and go on to the next field.
FORM_CLEAR Clear the form and move input cursor to
first available field.
FORM_ACCEPT Accept the current input in the form and
exit.
FIELD_NEWFIELD Move cursor to a new field and continue
editing from there.
FORM_EXIT_CLEAR Clear the form and quit editing.
FIELD_CONTINUE Stay in the button field.
The FIELD_PREVFIELD return value will move the input cursor to the
previous field in the form. If you try to move beyond the first
available field on the form the FORM_WRAP and/or the
FORM_EXIT_INITIAL form options will take action depending on
whether they are on or off. See CREATING FIELD ENTRIES for a
definition of the FORM_WRAP and FORM_EXIT_INITIAL options.
The FIELD_NEXTFIELD return value will move the input cursor to the
next field in the form. If you try to move beyond the first
available field in the form, the FORM_WRAP form option will take
action depending on whether this option was turned on.
The FORM_CLEAR return value clears the form of all input data and
moves the input cursor to the first available field.
Page 27 The C Data Forms Library Page 27
The FORM_ACCEPT return value accepts all the input from the input
fields and exits. The form is not exited automatically if the
FORM_CHECK option is on or if a field in the form has the
FIELD_CHECK option on. See CREATING FIELD ENTRIES for a definition
of the FORM_CHECK and FIELD_CHECK options.
The FORM_EXIT_CLEAR clears the form of all input and exits the
form. The form is not automatically cleared and exited if there is
an exit function defined for the form. Form exit functions are
discussed later in the manual.
The FIELD_CONTINUE_PROCESS is a 'do nothing and go on to the next
field' return value. Use this return value if you want the button
function to tell the form manager to go on to the next field (or
previous field, depending on the direction that the input cursor
was going). This return value is usually used if there is a
user-defined function defined, and only the side effects that the
user function may do is of any concern. For instance, the
user-defined function may display windows, and then return. You
would then return a FIELD_CONTINUE_PROCESS to the form manager to
state that you do not want anything special to be done.
The FIELD_NEWFIELD return value moves the input cursor to the field
assigned to the pointer in the third argument of the user-defined
function. This return value can only be used if you have a
user-defined function that is bound to the button field.
If you remember, the user-defined function's prototype passed a
pointer to the current field number. If you assign a field number
to the dereferenced pointer and the FIELD_NEWFIELD return value is
used, the form manager will move the input cursor to the field
desired. If the field entry does not exist, the form manager will
not move the input cursor. If the field is protected
(FIELD_PROTECT flag is on) for the desired field, the input cursor
is not moved.
FIELD_CONTINUE returns control to the button field. You cannot
exit this field if it is accepted. You can use this type of button
field to implement help and display help information.
Here is a small example of the BUTTON field:
#include "cwlform.h"
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
/* initialize entries for form 1 */
FIELD_ENTRY fentry[] = {BUTTON,1,1,"",' ',0,0,
NO_FIELD_OPTIONS,0,0,"",
BUTTON,1,10,"",
' ',0,0,NO_FIELD_OPTIONS,0,
0,"", FIELDEND};
FORMPTR form;
WPOINTER w;
main()
{
Page 28 The C Data Forms Library Page 28
int i;
int attr[2];
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
attr[NORMATTR] = NORM;
attr[HIATTR] = REVERSE;
/* Initialize form */
form = FormInitialize(w,fentry,FORM_HIGHLIGHT);
/* Let form know about button fields */
FormSetButtonField(form,1,FIELD_NEXTFIELD,"Accept",attr,
NO_BUTTON_FUNC);
FormSetButtonField(form,2,FORM_EXIT_CLEAR,"Abort",attr,
NO_BUTTON_FUNC);
WindowWriteCenterString(w,
"Use Left or Right Arrow Keys to move highlight",3);
/* get the input */
FormGetInput(form,1,1);
}
In the above example, two button fields are defined. The row and
column entries in the field description, fentry[], tells where the
button field will be placed. Note that the only meaningful entries
in the BUTTON field are its row and column in the form, and the
field options (the only option that can be used is FIELD_PROTECT).
All other arguments are meaningless (i.e. regular expression,
starting input position, etc.). The video attributes are derived
from the array of attributes given in the FormSetButtonField()
function.
When the form encounters the first button, the highlight is moved
to the position of the first button's prompt string. When the
user hits the 'accept' key, the return value FIELD_NEXTFIELD is
returned to the form manager, informing it to move the cursor to
the next field. A return value of FIELD_CONTINUE_PROCESS would
have accomplished the same thing. The highlight is then moved to
the next field, which is also a button field. When the user
accepts this field, the form is automatically exited.
If there are no errors, FormSetButtonField() will return NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to allocate for the
internal button data structure.
Page 29 The C Data Forms Library Page 29
Radio Fields and the RADIO_ENTRY structure
------------------------------------------
A radio field is a field that comprises a list of choices given to
the user. Only one of the choices can be chosen. Usually a radio
field is set up as a column and/or row of prompts with a 'floating'
character that goes from prompt to prompt when the user is
selecting an option. Unlike the LIST option, the radio field is
not a popup menu, but is comprised of text written to the form
window.
To set up a radio field, the field type must be initialized to
RADIO. This is done when initializing the array of field entries.
The next step is to initialize an array of RADIO_ENTRY structures.
Here is the layout for the RADIO_ENTRY structure:
char *prompt - Prompt string to write to the form window.
int hotkey_letter - Letter to highlight in prompt string.
unsigned prompt_row - row to write the prompt string.
unsigned prompt_col - column to write the prompt string.
unsigned button_row - row to write the radio button character.
unsigned button_col - column to write the radio button character.
An array of these structures is needed to complete the total radio
field definition. Here is an example:
RADIO_ENTRY radio_entry[] =
{"( ) Radio 1",'1',1,1,1,2, /* Radio Field 1 */
"( ) Radio 2",'2',2,1,2,2, /* Radio Field 2 */
"( ) Radio 3",'3',3,1,3,2, /* Radio Field 3 */
CWL_NULL}; /* Terminator */
Note that the variable radio_entry is an array of 3 RADIO_ENTRY's.
The first entry is a string that will be written to the window. In
the example above the first RADIO_ENTRY's prompt string is
"( ) Radio 1". The next entry is the character to highlight in the
prompt string. This character will serve as a 'hotkey'. When this
character is pressed, the radio button character will automatically
be placed at the desired choice. If no hotkey is desired, this
entry should be 0. The third and fourth entries are the (row,col)
coordinates of where the prompt is placed in the form window. The
fifth and sixth entries are the (row,col) coordinates of the
'floating' character. This character will be placed at the desired
position when the user moves the highlight from entry to entry.
Note that the above example strategically placed the floating
character in between the parentheses in each of the prompt strings.
This is the usual way to display a radio field, but you have the
flexibility to design your own layouts.
The array of RADIO_ENTRY's MUST be terminated with the CWL_NULL
constant. Leaving this out will cause unpredictable results.
Page 30 The C Data Forms Library Page 30
Once the array of RADIO_ENTRY's has been set up, the next thing is
to call the FormSetRadioField() function. This function binds the
RADIO_ENTRY's to the form, and defines attributes and the button
character to use for the radio field. Here is the prototype:
int FormSetRadioField (FORMPTR form, int entry,
RADIO_ENTRY *rptr, int rchar,
int start, int *attr)
The first two arguments are the form and the entry to assign the
RADIO_ENTRY's to. These must exist for the FormSetRadioField()
function to succeed. The third argument is the array of
RADIO_ENTRY's that was set up previously. The fourth argument is
the character that will float from choice to choice when the user
is deciding which selection to make. The fifth argument is the
starting entry to place the button character. Entry numbers are
numbered from 1 to the highest radio entry. The last argument is
an array of integers denoting the color attributes to use for the
radio field. Each element of this color array stands for a
different aspect of the radio field. Here are the constants that
denotes positions in the color array:
NORMATTR - This is the color of the unhighlighted entry.
HIATTR - This is the color of the highlighted entry. The
highlighted entry is the current entry that the
user has the choice of accepting. The highlight is
moved from entry to entry when the user hits the
appropriate keys. See GETTING INPUT FROM A FORM for a
discussion of these keys.
HOTATTR - This is the color of the hotkey.
UNAVAILATTR - This is the attribute to use for unavailable radio
entries. More on available and unavailable entries
later on.
To initialize an array that is large enough to hold the attributes,
Use the NUMRADIOCOLORS constant. This constant holds the number of
colors needed to define the radio field's color scheme.
Here is a small example of using FormSetRadioField():
#include "cwlform.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
RADIO_ENTRY radio_entry[] = {"( ) Radio 1",'1',1,1,1,2,
"( ) Radio 2",'2',2,1,2,2,
"( ) Radio 3",'3',3,1,3,2,
CWL_NULL};
Page 31 The C Data Forms Library Page 31
FORMPTR form;
FIELD_ENTRY field[] = {RADIO,0,0,"",' ',NO_FIELD_OPTIONS,0,0,"",
FIELDEND};
/* Initialize array of colors */
int attr[NUMRADIOCOLORS];
main()
{
int retval;
/* Assume form is initialized */
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
retval = FormSetRadioField(form,1,radio_entry,7,1,attr);
if (retval != NO_ERROR)
/* some error message */
}
The above call to FormSetRadioField() uses the FORMPTR form and
field entry 1 (this is the RADIO field). The array, radio_entry,
is used as the array of RADIO_ENTRY's. The ASCII character 7 is
used as the floating button character. The IBM PC character set
defines this as the 'bullet' character. This character is usually
used for radio fields, but you can use any ASCII character you
desire (however, I highly recommend NOT using the space character!).
The fifth argument starts the radio button character on the first
radio entry.
If there are no errors, FormSetRadioField() and will return
NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to allocate for the
internal radio field data structure.
Deactivating and Activating Radio Entries
-----------------------------------------
If FormSetRadioField() is successful, all of the radio entries are
available for the user to choose from. However, there may be
situations where you may want some options disabled. To disable
radio entries use the FormDeactivateRadioEntry() function. Here is
the prototype to the function:
int FormDeactivateRadioField(FORMPTR form, int entry, int radionum)
Page 32 The C Data Forms Library Page 32
The first two arguments are the form and entry number of where to
find the radio entry. The last argument is the entry in the radio
field to deactivate. The reason for using the form and entry to
find the radio field is that you can use the same radio field in
different forms. Therefore you must supply the form and entry
number to find the radio field. Once the radio entry is found, the
prompt string for the desired radio entry takes on the UNAVAILATTR
color. Also this field is skipped automatically when the user is
moving the button character from field to field.
To reactivate a field, the FormActivateRadioEntry() function is
used. Here is the prototype:
int FormActivateRadioEntry(FORMPTR form, int entry, int radionum)
The arguments have the same definition as the
FormDeactivateRadioEntry(). The radio entry is automatically given
its NORMATTR color.
Retrieving the Radio selection
------------------------------
To find out what selection was made in the radio field, use the
FormGetRadioChoice() function. This function returns the number
of the radio entry that was chosen. Radio entries are numbered
from 1 to the highest entry. Entries are numbered as they are
ordered in the RADIO_ENTRY array. Here is the prototype to the
function:
int FormGetRadioChoice(FORMPTR form, int entry)
The only arguments are the form and field entry where the radio
field is defined. Here is a small example:
#include "cwlform.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
RADIO_ENTRY radio_entry[] = {"( ) Radio 1",'1',1,1,1,2,
"( ) Radio 2",'2',2,1,2,2,
"( ) Radio 3",'3',3,1,3,2,
CWL_NULL};
FORMPTR form;
FIELD_ENTRY field[] = {RADIO,0,0,"",' ',0,0,NO_FIELD_OPTIONS,0,0,"",
FIELDEND};
int attr[NUMRADIOCOLORS];
WPOINTER w;
Page 33 The C Data Forms Library Page 33
main()
{
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,COLOR1,COLOR1,SINGLEBOX);
WindowOpen(w);
/* Initialize form */
form = FormInitialize(w,field,FORM_HIGHLIGHT|FORM_STATIC);
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
FormSetRadioField(form,1,radio_entry,7,1,attr);
WindowWriteCenterString(w,
"Hit TAB to accept, Up or Down Arrows to change choice",4);
FormGetInput(form,1,1);
WindowMoveCursor(w,5,20);
VideoPrintf("The radio choice was %d",FormGetRadioChoice(form,1));
}
The example above sets up a radio field, gets the input from the
form, and then prints the radio entry that was chosen. You can
call the FormGetRadioChoice() at any time, even in user-defined
functions that may be performed while the form is active.
If successful, FormGetRadioChoice() returns the current radio entry
that is chosen. If all of the radio entries are deactivated, or
the radio field is a protected field (no input will be accepted),
the return value is 0.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Checkbox Fields and the CHECKBOX_ENTRY structure
------------------------------------------------
A checkbox field is a field that comprises a list of choices given
to the user. Any number of these choices can be selected. This
differs from the radio field defined above in that the radio
fields only allowed one selection.
To set up a checkbox field, the field type must be initialized to
CHECKBOX. This is done when initializing the array of field
entries.
Page 34 The C Data Forms Library Page 34
The next step is to initialize an array of CHECKBOX_ENTRY
structures. Here is the layout for the CHECKBOX_ENTRY structure:
char *prompt - Prompt string to write to the form window.
int hotkey_letter - Letter to highlight in prompt string.
unsigned prompt_row - row to write the prompt string.
unsigned prompt_col - column to write the prompt string.
unsigned button_row - row to write the checkbox button character.
unsigned button_col - column to write the checkbox button
character.
An array of these structures is needed to complete the total
checkbox field definition. Here is an example:
CHECKBOX_ENTRY checkbox_entry[] =
{"[ ] Check 1",'1',1,1,1,2, /* Checkbox field 1 */
"[ ] Check 2",'2',2,1,2,2, /* Checkbox field 2 */
"[ ] Check 3",'3',3,1,3,2, /* Checkbox field 3 */
CWL_NULL}; /* Terminator */
Note that the variable checkbox_entry is an array of 3
CHECKBOX_ENTRY's. The first entry is a string that will be written
to the window. In the example above the first CHECKBOX_ENTRY's
prompt string is "[ ] Check 1". The next entry is the character to
highlight in the prompt string. This character will serve as a
'hotkey'. When this character is pressed, the checkbox button
character will automatically be placed at the desired choice. If
no hotkey is desired, this entry should be 0. The third and fourth
entries are the (row,col) coordinates of where the prompt is placed
in the form window. The fifth and sixth entries are the (row,col)
coordinates of the checkbox character. This character will be
placed at the desired position when the choice is selected. Note
that the above example strategically placed the checkbox character
in between the brackets in each of the prompt strings. This is
the usual way to display a checkbox field, but you have the
flexibility to design your own layouts.
The array of CHECKBOX_ENTRY's MUST be terminated with the CWL_NULL
constant. Leaving this out will cause unpredictable results.
Once the array of CHECKBOX_ENTRY's has been set up, the next thing
is to call the FormSetCheckboxField() function. This function
binds the CHECKBOX_ENTRY's to the form, and defines attributes and
the button character to use for the checkbox field. Here is the
prototype:
int FormSetCheckboxField (FORMPTR form, int entry,
CHECKBOX_ENTRY cptr[], int cchar,
int start, int *attr)
Page 35 The C Data Forms Library Page 35
The first two arguments are the form and the entry to assign the
CHECKBOX_ENTRY's to. These must exist for the FormSetCheckbox()
function to succeed. The third argument is the array of
CHECKBOX_ENTRY's that was set up previously. The fourth argument
is the character that will be placed in when the entry is selected.
The fifth argument is the checkbox entry to place the cursor when
the field is initially edited. The last argument is an array of
integers denoting the color attribute to use for the checkbox
field. Each element of this color array stands for a different
aspect of the checkbox field. Here are the constants that denotes
positions in the color array:
NORMATTR - This is the color of the unhighlighted entry.
HIATTR - This is the color of the highlighted entry. The
highlighted entry is the current entry that the
user has the choice of accepting. The highlight is
moved from entry to entry when the user hits the
appropriate keys. See GETTING INPUT FROM A FORM for a
discussion of these keys.
HOTATTR - This is the color of the hotkey.
UNAVAILATTR - This is the attribute to use for unavailable checkbox
entries. More on available and unavailable entries
later on.
To initialize an array that is large enough to hold the attributes,
Use the NUMCHECKBOXCOLORS constant. This constant holds the number of
colors needed to define the checkbox field's color scheme.
Here is a small example of using FormSetCheckboxField():
#include "cwlform.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
CHECKBOX_ENTRY checkbox_entry[] = {"[ ] Check 1",'1',1,1,1,2,
"[ ] Check 2",'2',2,1,2,2,
"[ ] Check 3",'3',3,1,3,2,
CWL_NULL};
FORMPTR form;
FIELD_ENTRY field[] = {CHECKBOX,0,0,"",' ',0,0,NO_FIELD_OPTIONS,
"", FIELDEND};
int attr[NUMCHECKBOXCOLORS];
WPOINTER w;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
Page 36 The C Data Forms Library Page 36
w = WindowInitialize(BORDER,1,1,78,22,COLOR1,COLOR1,SINGLEBOX);
WindowOpen(w);
/* Initialize form */
form = FormInitialize(w,field,FORM_HIGHLIGHT);
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
FormSetCheckboxField(form,1,checkbox_entry,'X',1,attr);
}
The above call to FormSetCheckboxField() uses the FORMPTR form and
field entry 1 (this is the CHECKBOX field). The array,
checkbox_entry, is used as the array of CHECKBOX_ENTRY's. The
'X' character is used as the checkbox character. This character is
usually used for checkbox fields, but you can use any ASCII
character you desire (as stated before, I highly recommend NOT
using the space character!).
If there are no errors, FormSetCheckboxField() and will return
NO_ERROR.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
NO_HEAP_MEM if there is not enough memory to allocate for the
internal checkbox field data structure.
Deactivating and Activating Checkbox Entries
--------------------------------------------
If FormSetCheckboxField() is successful, all of the checkbox
entries are available for the user to choose from. However, there
may be situations where you may want some options disabled. To
disable checkbox entries use the FormDeactivateCheckboxEntry()
function. Here is the prototype to the function:
int FormDeactivateCheckboxField(FORMPTR form, int entry,
int checkboxnum)
The first two arguments are the form and entry number of where to
find the checkbox entry. The last argument is the entry in the
checkbox field to deactivate. The reason for using the form and
entry to find the checkbox field is that you can use the same
checkbox field in different forms. Therefore you must supply the
Page 37 The C Data Forms Library Page 37
form and entry number to find the checkbox field. Once the
checkbox entry is found, the prompt string for the desired checkbox
entry takes on the UNAVAILATTR color.
To reactivate a field, the FormActivateCheckboxEntry() function is
used. Here is the prototype:
int FormActivateCheckboxEntry(FORMPTR form, int entry,
int checkboxnum)
The arguments have the same definition as the
FormDeactivateCheckboxEntry(). The checkbox entry is automatically
given its NORMATTR color.
Retrieving the checkbox selection
---------------------------------
To find out whether a checkbox entry was selected, use the
FormGetCheckboxChoice() function. This function returns 1 if the
entry is selected, 0 otherwise. Checkbox entries are numbered
from 1 to the highest entry. Entries are numbered as they are
ordered in the CHECKBOX_ENTRY array. Here is the prototype to the
function:
int FormGetCheckboxChoice(FORMPTR form, int entry, int cboxentry)
The arguments are the form and field entry where the checkbox
field is defined. The last argument is the checkbox entry to
test to see if it was selected. Here is a small example:
#include "cwlform.h"
#define COLOR1 CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define COLOR2 CREATE_VIDEO_ATTRIBUTE(BLACK_,LIGHTWHITE_)
#define COLOR3 COLOR2
#define COLOR4 COLOR1
CHECKBOX_ENTRY checkbox_entry[] = {"[ ] Check 1",'1',1,1,1,2,
"[ ] Check 2",'2',2,1,2,2,
"[ ] Check 3",'3',3,1,3,2,
CWL_NULL};
FORMPTR form;
FIELD_ENTRY field[] = {CHECKBOX,0,0,"",' ',0,0,NO_FIELD_OPTIONS,
0,0,"", FIELDEND};
int attr[NUMCHECKBOXCOLORS];
WPOINTER w;
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
Page 38 The C Data Forms Library Page 38
w = WindowInitialize(BORDER,1,1,78,22,COLOR1,COLOR1,SINGLEBOX);
WindowOpen(w);
/* Initialize form */
form = FormInitialize(w,field,FORM_HIGHLIGHT|FORM_STATIC);
attr[NORMATTR] = COLOR1;
attr[HIATTR] = COLOR2;
attr[HOTATTR] = COLOR3;
attr[UNAVAILATTR] = COLOR4;
FormSetCheckboxField(form,1,checkbox_entry,'X',attr);
WindowWriteCenterString(w,
"Hit TAB to accept, Space Bar to toggle, Arrow keys to change"
"choice",4);
FormGetInput(form,1,1);
WindowMoveCursor(w,6,1);
for (i=1; i<=3; i++)
VideoPrintf("Checkbox choice %d was %s chosen\n",i,
FormGetCheckboxChoice(form,1,i)?"":"not");
}
The example above sets up a checkbox field, gets the input from the
form, and then loops to see if any checkboxes were selected. The
string "not" is printed if FormGetCheckboxChoice() returns 0, else
an empty string is printed. FormGetCheckboxChoice() can be called
at any time, even in user-defined functions that may be performed
while the form is active.
FormGetCheckboxChoice() returns 1 if the choice was selected, 0
otherwise.
If there are errors the return value is one of the following
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Page 39 The C Data Forms Library Page 39
GETTING INPUT FROM A FORM
-------------------------
The following section discusses how to call functions that process
the input form.
FormGetInput()
--------------
The FormGetInput() function processes a form. Here is a
prototype:
int FormGetInput(FORMPTR form, int rank, int start)
or
int FormGetInput(FORMPTR form, int rank, int start, WPOINTER w)
The first prototype is for non-virtual forms (regular windows are
used).
The second prototype is for virtual forms. The second prototype's
last argument is a pointer to window. This window is the viewport
that is currently assigned to the virtual window used to
initialize the FIELD_ENTRY's. This parameter is necessary since
the form manager only knows what the virtual window is, and has no
record of the viewport (since a virtual window can have multiple
viewports).
The first argument to FormGetInput() is the pointer to a form.
This form must have been previously initialized with
FormInitialize().
The second argument is the rank of the window the form is going to
be displayed on.
The third argument is the field entry to start the input from.
Field entries are numbered from 1 to the highest field defined in
the form. If the field is protected, a circular search for the
next available field is done. For example , if there are 6
fields, and field 5 is protected, field 6 is the next available
field. However if field 6 is protected, field 1 is the next
available field.
The fourth argument, as discussed above, is an optional argument.
This argument must be used if you are using a virtual form.
If there are no errors, FormGetInput() returns NO_ERROR.
If there are errors, FormGetInput() returns one of the following
and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
BAD_WINDOW if the viewport window does not exist.
Page 40 The C Data Forms Library Page 40
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
FIELD_ENTRY field_array[] =
/* define first field entry */
{INTEGER,1,20,"___",'_',1,3,FIELD_RJUSTIFY,NORM,"3[0-9]",
STRING, 2, 20, "__________", '_', 0, 10, NO_FIELD_OPTIONS,
1,NORM, "10.",
INTEGER,3, 20, "__", '_', 2, 2,NO_FIELD_OPTIONS, 1,NORM,
"2[0-9]",
DOUBLE,4, 20, "_______",'_',1,7,FIELD_COMMA|FIELD_LJUSTIFY,
1,NORM,"7[0-9/.]",
CHAR, 5, 20,"_", '_', 1, 1, FIELD_UPPERCASE, 1,NORM,
"[YyNn]",
FIELDEND};
WPOINTER w;
FORMPTR form;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,40,10,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
NO_FORM_OPTIONS); /* form options */
if (form == FORM_NULL_PTR)
{
printf("Form could not be initialized");
exit(0);
}
FormGetInput(form,1,1); /* Get Input for the form */
}
Virtual Form Scrolling
----------------------
If the form is a virtual form, the form is scrolled automatically
to the desired field if the field is not currently in the
viewport. If the form has to be scrolled up or down, the field
will come into view on the last line of the viewport or the first
line, depending on whether the form was scrolled up or down to
bring the field into view.
If the form has to be scrolled left or right to bring the field in
view, the field will either be brought in so that it is right
justified in the viewport, or will appear on the left edge of the
viewport depending on whether the form manager had to scroll the
form left or right.
Page 41 The C Data Forms Library Page 41
Editing Input
-------------
When getting input from a form, the following key definitions are
used as the defaults:
Offset in Key
Function Key Table
-------- --- -------------
Move cursor left Left Arrow FIELD_MOVELEFT_KEY
Move cursor right Right Arrow FIELD_MOVERIGHT_KEY
Delete character Del (on keypad) FIELD_DELNOMOVE_KEY
Toggle Insert/Overwrite Insert (on keypad) FIELD_INSTOGGLE_KEY
Erase Input ^E FIELD_ERASE_KEY
Destructive backspace Backspace FIELD_BACKSPACE_KEY
Accept Input and goto Enter FIELD_ACCEPT_KEY
next field.
Accept default and Not Assigned FIELD_ACCEPTDEFAULT_KEY
return
Go to first column Home FIELD_HOME_KEY
Move cursor to last End FIELD_END_KEY
character
Go to previous field Up Arrow FIELD_PREVFIELD_KEY
Go to next field Down Arrow FIELD_NEXTFIELD_KEY
Toggle Field Space Bar FIELD_TOGGLE_KEY
Button Accept key Enter BUTTON_ACCEPT_KEY
Button Move to next Right Arrow BUTTON_NEXTFIELD_KEY
field
Button Move to prev Left Arrow BUTTON_PREVFIELD_KEY
field
Move Radio button to Down Arrow RADIO_NEXTENTRY_KEY
next entry
Move Radio button to Up Arrow RADIO_PREVENTRY_KEY
previous entry
Move to next field from Tab RADIO_NEXTFIELD_KEY
radio field
Move to previous field ShiftTab RADIO_PREVFIELD_KEY
from radio field
Page 42 The C Data Forms Library Page 42
Select/deselect Space Bar CHECKBOX_CHOICE_KEY
checkbox entry
Move checkbox cursor to Down Arrow CHECKBOX_NEXTENTRY_KEY
next checkbox entry
Move checkbox cursor to Up Arrow CHECKBOX_PREVENTRY_KEY
previous checkbox entry
Move to next field from Tab CHECKBOX_NEXTFIELD_KEY
checkbox field
Move to previous field ShiftTab CHECKBOX_PREVFIELD_KEY
checkbox field
Accept form ^S FORM_EXIT_ACCEPT_KEY
Escape form Escape FORM_EXIT_CLEAR_KEY
Clear Form ^End FORM_CLEAR_KEY
Here is a list of what the key functions perform:
Move cursor left - Moves the cursor left one character. If the
beginning of the input field is encountered the
cursor is not moved.
Move cursor right - Moves the cursor right one character. If the
end of the input field is encountered, the
cursor is not moved.
Delete character at cursor - Deletes the character at the position
of the cursor. If in insert mode,
any input to the right of the
cursor is moved one character to
the left. If in overwrite mode, no
characters are moved.
Toggle Insert/Overwrite Mode - toggles the input between insert and
overwrite mode. If in insert mode,
the default cursor is an underline
cursor. If in overwrite mode, the
default cursor is a full block.
Erase Input - Deletes all characters inputted and moves the cursor
to the first input position.
Destructive Backspace - deletes the character immediately to the
left of the cursor and moves the cursor to
the left one character. If insert mode is
on, the characters from the current cursor
position to the end of the input field are
also moved.
Page 43 The C Data Forms Library Page 43
Accept string - Accepts the string that is inputted and returns the
string. Also goes to next field by default.
Accept default and return - Returns the default string given to the
input routine.
Go to first column in field - Moves cursor to the first input
position.
Go to last character in field - Moves cursor to the last character
in the current input string.
Go to previous field - Moves input cursor to the first character in
the previous field. If field is field 1 or
first available field, the input cursor is
moved to the last input field if the
FORM_WRAP option is on, otherwise the input
cursor is not moved.
Go to next field - Moves the input cursor to the first character in
the next field in sequence.
Toggle field - Displays next choice in a TOGGLE field. Only is
active for TOGGLE field. Undefined for other
fields.
Button Accept - Accepts the BUTTON field and will perform
whatever the buttons return value was.
Button Move to next field - Moves to the next field from a button
Does not accept the button field.
Button move to prev. field - Moves to previous field from a button
field. Does not accept the button
field.
Move Radio button to next radio entry - moves the highlight in the
radio entry to the next
available radio entry.
Move Radio button to prev. radio entry - moves the highlight in
the radio entry to the
previous radio entry.
Move to next field from radio - moves to the next field from a
radio field.
Move to prev. field from radio - moves to the previous field from a
radio field.
Select/Deselect checkbox entry - toggles checkbox entry for
selection/delection.
Move to next checkbox entry - moves the highlight to the next
checkbox entry.
Page 44 The C Data Forms Library Page 44
Move to prev. checkbox entry - moves the highlight to the previous
checkbox entry.
Move to next field from checkbox - moves to the next field from a
checkbox field.
Move to prev. field from checkbox - moves to the previous field
from a checkbox field.
Accept form - Accepts the input to a form, and exits
processing the form.
Escape form and do not accept - Exits form without accepting the
input to any fields.
Clear Form - clears all input in a form and moves the cursor to the
first available field.
Changing the Editing Key definitions globally using the
form_edit_key table
-------------------
You can change the key definitions globally (all fields will have
the same key definitions) by changing the form_edit_key array of
values. The mapped position is the offset in a table of field key
functions. By changing the value there, you can change the keys
used to perform these functions. If you do want to change these
keys, I recommend using the key definitions found in the keycodes.h
file. For example, if you wanted tab key to be the advance to next
field key you would do the following:
form_edit_key[FIELD_NEXTFIELD_KEY] = TAB;
The table of key functions is stored in the array form_edit_key.
The TAB definition is found in the keycodes.h file. To totally
undefine a key definition, assign a 0 to the desired array position
in window_edit_key. For example:
form_edit_key[FIELD_DELNOMOVE_KEY] = 0;
undefines the delete character at cursor definition.
When changing keys, make sure that the definitions all have unique
key combinations. If you desire more keystrokes for a particular
key function, see Undefined Form Keystroke Processing below.
Changing the Editing Key definitions using FormAssignFieldKeys()
----------------------------------------------------------------
The FormAssignFieldKeys() assigns a key definition to a particular
field. In other words, each field can have its own set of editing
key definitions. Here is the prototype:
int FormAssignFieldKeys(FORMPTR form, int entrynum,
unsigned *keydef)
Page 45 The C Data Forms Library Page 45
The first argument is the pointer to the form. The form must have
been successfully initialized with FormInitialize().
The second argument is the field entry number to assign these key
definitions to. As stated before, entry numbers are labeled from 1
to the highest entry number in the form.
The third argument is an array of key definitions. This array must
be analogous to the form_edit_key array.
Example:
#include "cwlform.h"
#include <string.h>
/* ... define everything ... */
unsigned newkeys[NUMFORMKEYS];
FORMPTR form;
FIELD_ENTRY field_entry[] = { /* .. Field definitions ... */ };
WPOINTER w;
main()
{
WindowInitializeSystem();
FormInitializeSystem();
/* ... assume Form Initialization stuff has been done ... */
/* copy old key definitions to the new array */
memcpy(newkeys,form_edit_key,sizeof(form_edit_key));
/* assign desired keys */
newkeys[FIELD_NEXT_KEY] = TAB;
newkeys[FIELD_PREV_KEY] = SHIFTTAB;
/* Assign this key definition to second field entry */
FormAssignFieldKeys(form,2,newkeys);
}
Note that the constant NUMFORMKEYS was used to make sure that our
newkeys array was large enough to hold all the key definitions.
Also note the shortcut that was taken with the memcpy() function.
This copied all the old key definitions to the newkeys array. Both
the newkeys array and the form_edit_key array are guaranteed to be
the same size if the constant NUMFORMKEYS is used.
If there are no errors, FormAssignFieldKeys() returns NO_ERROR.
If there are errors, FormAssignFieldKeys() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 46 The C Data Forms Library Page 46
Traversing fields and the FORM_HIGHLIGHT option
-----------------------------------------------
When going from field to field, you can have each field take on the
field color only when they are the active field (field currently
being input). This will happen if the FORM_HIGHLIGHT option is on.
If the field is not the active field, the field takes on the same
color as the window or the viewport text color.
If the FORM_HIGHLIGHT option is off, each field will take on its
field color even if they are not the current field.
Page 47 The C Data Forms Library Page 47
ASSIGNING VALUES TO AND RETRIEVING VALUES FROM A FORM
-----------------------------------------------------
When you edit an input field, you are entering just a string of
characters. The C Data Forms Library's form manager will
automatically convert these strings to the correct data type, and
assign these values to specified variables when a form is exited,
or whenever you want to retrieve the data.
The field type determines what type of conversion will be done.
The supported types are the normal C types. The SUBFORM,
VSUBFORM, BUTTON, RADIO, and CHECKBOX fields do not have a return
type. The LIST field returns the string in the popup menu
that was selected. The TOGGLE field returns the string that was
chosen in the toggle field list.
FormSetFieldVariable()
----------------------
The FormSetFieldVariable() function assigns a variable to a
particular field in a form. When the form is exited, the data is
converted and transferred to the variable specified. Here is the
prototype:
int FormSetFieldVariable(FORMPTR form, int entrynum,
void *uservar, int display)
The first argument is the pointer to a form.
The second argument is the field entry to assign the user variable
to.
The third argument is a pointer to the user variable.
The fourth argument is a flag to tell the form manager whether to
display the value in the variable on the form. If display is TRUE,
the variable's value is automatically displayed in the form. If
display is FALSE, the variable's value is not displayed in the
form. No matter what the last argument is, the address of the
variable is assigned to the form.
If the field type is TOGGLE or LIST, these types translate to
string types because a string will ultimately be displayed in the
field when a selection is made for these two types. SUBFORM's,
VSUBFORM's, BUTTON's, RADIO's and CHECKBOXes have no corresponding
C data type, therefore you cannot assign a variable to these field
types.
Example:
#include "cwlform.h"
#include <string.h>
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(_WHITE,_BLACK)
FORMPTR form;
Page 48 The C Data Forms Library Page 48
FIELD_ENTRY field_entry[] =
{INTEGER,1,20,"_____",' ',1,5,NO_FIELD_OPTIONS,1,REVERSE,"5[0-9]",
ULINTEGER,2,20,"_________",' ',1,9,NO_FIELD_OPTIONS,1,REVERSE,
"9[0-9]",
FIELDEND};
WPOINTER w;
main()
{
int intvar = 123; /* define integer and long variables */
unsigned long lvar = 456L;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,60,4,NORM,NORM,SINGLEBOX);
WindowOpen(w);
form = FormInitialize(w,field_entry,FORM_HIGHLIGHT);
/* Set user variables */
FormSetFieldVariable(form,1,&intvar,TRUE);
FormSetFieldVariable(form,2,&lvar,TRUE);
FormGetInput(form,1,1);
VideoPrintf(
"The value of intvar is %d.\nThe value of lvar is %ul",
intvar,lvar);
}
When the form is exited, the variables intvar and lvar have the
values automatically converted.
If you change the value of a variable that is assigned to a field,
the field is not updated. Use the FormPutFieldData() to change
the value of a field.
Warning! You must make sure that you assign the pointer to a
variable of the correct type. If not, you may overwrite memory
when the conversion takes place.
Placing input in a form with FormPutFieldData()
-----------------------------------------------
You can write the value of a variable or an expression to a field
at anytime using the FormPutFieldData() function. Here is the
prototype:
int FormPutFieldData(FORMPTR form, int entry, ...)
The first argument is the form, and the second is the entry number.
The last argument third is the value to write to the field. Note
that the ellipses are used when prototyping the last argument. The
reason for this is that the variable or expression can be of any
type, therefore the undefined third argument.
Page 49 The C Data Forms Library Page 49
You should make sure that the variable/expression translates to the
same data type as the field type. There is no harm done if you
have an expression of a different type than the field, but you may
get weird characters in the field when it is displayed.
Here is an example:
#include "cwlform.h"
/* assume everything is initialized */
main()
{
int intvar = 0;
long lvar = 2;
/*...*/
FormPutFieldData(form,1,intvar); /* place value of intvar in
entry 1 */
FormPutFieldData(form,2,lvar); /* place value of lvar in
entry 2 */
FormPutFieldData(form,1,3+5*6); /* place value of expression in
entry 1 */
/* ... */
}
If there are errors, FormPutFieldData() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Retrieving Input with FormGetFieldData()
----------------------------------------
You can retrieve and convert the string entered in a field at any
time, including if the form has been exited, with the
FormGetFieldData() function. Here is the prototype:
int FormGetFieldData(FORMPTR form, int entrynum, void *uservar)
The first and second arguments are the form and field entry number,
respectively.
The third argument is the pointer to the desired variable to assign
this value to.
Example:
#include "cwlform.h"
FORMPTR form;
FIELD_ENTRY field[] = {INTEGER, /* other initializations */ };
int myvar;
Page 50 The C Data Forms Library Page 50
main()
{
/* assume everything is initialized */
/* get what was entered in field 1 and copy converted
value to myvar */
FormGetFieldData(form,1,&myvar);
}
Warning! You must make sure that you assign the pointer to a
variable of the correct type. If not, you may overwrite memory
when the conversion takes place.
If there are no errors, FormGetFieldData() returns NO_ERROR.
If there are errors, FormGetFieldData() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Pre-filling a form with default data with FormInitializeFieldData()
-------------------------------------------------------------------
You can pre-fill a form with data before you start getting input
from the form. The only restriction is that the data must be in
string form.
The FormInitializeFieldData() partially or totally initializes a
form with default data. The data must be in string form. Here is
the prototype:
int FormInitializeFieldData(FORMPTR form, char **data, int start,
int end)
The first argument is the pointer to a form.
The second argument is a pointer to an array of characters. This
will be dealt with in depth later on.
The third and fourth arguments are the starting entry to initialize
and the ending entry to initialize. FormInitializeFieldData()
initializes a range of field entries. If the ending entry number
is less than the starting entry number, the ending entry number
will be made equal to the starting entry number.
Setting up array of strings using Allocate2DArray() function
------------------------------------------------------------
There are many ways to set up the array of strings required for the
second argument to FormInitializeFieldData(). Here are various
methods of assigning "123" to an array of strings:
Page 51 The C Data Forms Library Page 51
/* Method 1 */
#include <string.h>
char data[5][4];
FORMPTR form;
main()
{
int i;
/* ... assume form already initialized */
/* copy "123" to data array */
for (i=0;i<4;i++)
strcpy(data[i],"123");
FormInitializeFieldData(form,data,1,5);
}
/* Method 2 */
#include <string.h>
char *data[5] = {
"123",
"123",
"123",
"123",
"123" };
main()
{
/* ... assume form already initialized */
FormInitializeFieldData(form,data,1,5);
}
/* Method 3 */
#include "cwlform.h"
char **data;
main()
{
data = (char **)Allocate2DArray(5,4,sizeof(char));
for (i=0;i<5;i++)
strcpy(data[i],"123");
FormInitializeFieldData(form,data,1,5);
}
The first two methods are self-explanatory, or if they are not, any
elementary book on C programming will explain the methods used to
initialize an array of strings.
Page 52 The C Data Forms Library Page 52
The third method dynamically allocates memory for a two dimensional
array. Note the use of the function Allocate2DArray(). This
function allocates a two dimensional array from the heap. The
first and second arguments to this function are the number of rows
and columns in the array, respectively. The third argument is the
size of each data element (in bytes) in the array. Since we want
to initialize a two dimensional array of five strings with 4
characters for each string (you should allow an extra character for
the terminating null for each string), the size of each element
will be the size of one character. Note the use of sizeof() to
determine the size of a character.
You can use Allocate2DArray() with any data type. You must make
sure that the return value is cast to the proper pointer type,
since the returning data type is a void pointer (This rule is
relaxed for C programs, but it is strictly enforced in C++
programs).
Allocate2DArray() returns a null pointer if it cannot allocate the
memory desired. You can allocate up to 64K of memory with this
function. To calculate the amount of memory that will be
allocated, you should use the following formula:
rows X cols X sizeof(each data element)
The prototype for this function is include in the window.h file.
Since cwlform.h includes window.h, there was no need to explicitly
include window.h in any of the examples.
Freeing a two dimensional array with Free2DArray()
--------------------------------------------------
If you want to dispose of a two dimensional array allocated with
Allocate2DArray(), you should use the Free2DArray() function. The
prototype is as follows:
void Free2DArray(void **array)
The only argument is the pointer to the two dimensional array.
Since this function does not return anything, you must make sure
that you are actually freeing a valid two dimensional array.
Using FormInitializeFieldData()
-------------------------------
As was stated above, FormInitializeFieldData() can totally or
partially fill a form with default data. The number of fields that
will be filled is determined by the starting and ending field entry
numbers, which are denoted by the third and fourth arguments to
FormInitializeFieldData(). For instance if the starting entry is 1
and the ending entry is 5, the form manager will start filling in
the fields 1 through 5 with the data stored in the array of
strings, which was passed as the second argument, to
FormInitializeFieldData(). If a CWL_NULL is encountered in the
array of strings before the last entry specified is reached,
Page 53 The C Data Forms Library Page 53
FormInitializeFieldData() will stop initializing fields and will
return NO_ERROR. FormInitializeFieldData() should be called before
calling FormGetInput().
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE,BLACK_)
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,2,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
STRING,3,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,4,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
UINTEGER,5,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
CHAR,6,35,"_",'_',1,1,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"[YyNn]",
CHAR,7,35,"_",'_',1,1,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"[YyNn]",
INTEGER,8,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
FIELDEND};
WPOINTER w;
FORMPTR form;
char *data[8] = {
"123",
"0",
"ABC",
"200",
"230",
"N",
"Y",
"100"};
main()
{
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,40,10,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* Initialize with WPOINTER */
form = FormInitialize(w, /* window to assign form to */
field_array, /* array of fields */
FORM_HIGHLIGHT); /* form options */
if (form == FORM_NULL_PTR)
{
printf("Form could not be initialized");
exit(0);
}
Page 54 The C Data Forms Library Page 54
FormInitializeFieldData(form,data,1,8);
FormGetInput(form,1,1); /* Get Input for the form */
}
If there are no errors, FormInitializeFieldData() returns NO_ERROR.
If there are errors, FormInitializeFieldData() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the starting field does not exist.
Page 55 The C Data Forms Library Page 55
SETTING FIELD OPTIONS
---------------------
In the previous sections, the field options were set up during
initialization of the field entries. You can also set field
options at any time. If you want to set field options during form
input there are some restrictions.
FormSetFieldOptions()
---------------------
The FormSetFieldOptions() function turns on or off field options.
Here is the prototype:
int FormSetFieldOptions(FORMPTR form, int entrynum, int options,
int flag)
The first and second arguments are the form and the field entry
number, respectively.
The third arguments are the options desired. The fourth arguments
tell us whether to turn these options on or off. If flag is equal
to 1, the options are turned on. If flag is 0, the options are
turned off.
The field options are the same options specified in the CREATING
FIELD ENTRIES section above. Multiple field options can be
specified by using the bitwise OR (|) between field option
constants, just as before.
The field option that you would probably use this function for most
of the time is the FIELD_PROTECT option. As defined, if the
FIELD_PROTECT option is on, the form manager will skip over this
field and will go to the next available field. You will probably
want to toggle a field's FIELD_PROTECT option during input of a
form.
It is advised NOT to change the field options of a particular field
if the field is currently being edited. This may lead to undesired
results.
#include "cwlform.h"
FORMPTR form;
/* ... skip other initializations ... */
main()
{
/* ... skip initializations ... */
/* set field protect option */
FormSetFieldOptions(form,1,FIELD_PROTECT,1);
/* turn off field protect option */
FormSetFieldOptions(form,1,FIELD_PROTECT,0);
}
Page 56 The C Data Forms Library Page 56
If there are no errors, FormSetFieldOptions() returns NO_ERROR.
If there are errors, FormSetFieldOptions() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 57 The C Data Forms Library Page 57
SETTING FORM OPTIONS
--------------------
In the previous sections, the form options were set up when
FormInitialize() was called. You can also set form options at any
time, including during input of a form.
FormSetOptions()
----------------
The FormSetOptions() function turns on or off form options. Here
is the prototype:
int FormSetOptions(FORMPTR form, int options, int flag)
The first argument is the pointer to the form.
The second argument are the options desired. The third argument
tells us whether to turn these options on or off. If flag is equal
to 1, the options are turned on. If flag is 0, the options are
turned off.
The form options are the same options specified in the
FormInitialize() function, which is described in the CREATING FIELD
ENTRIES section above. Multiple form options can be specified by
using the bitwise OR (|) between form option constants, just as
before.
You should not use the FORM_VIRTUAL or FORM_HIGHLIGHT options in
this function. The FormInitialize() function uses these options to
set up the form, and assumes the form will remain a virtual or
windowed form throughout the life of the form. The form manager
also assumes that the FIELD_HIGHLIGHT option remains the same
throughout the life of the form.
#include "cwlform.h"
FORMPTR form;
/* ... skip other initializations ... */
main()
{
/* ... skip initializations ... */
form = FormInitialize( /* arguments to FormInitialize */ );
/* set form checking option */
FormSetOptions(form,1,FORM_CHECK_ON,1);
/* turn off form checking option */
FormSetOptions(form,1,FORM_CHECK_OFF,0);
}
Page 58 The C Data Forms Library Page 58
If there are no errors, FormSetOptions() returns NO_ERROR.
If there are errors, FormSetOptions() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the form does not exist.
INVALID_FIELD_OPTION if FORM_VIRTUAL or FORM_HIGHLIGHT is used as
an option.
Page 59 The C Data Forms Library Page 59
WRITING VALUES TO THE FIELD BUFFER
----------------------------------
You can write values to the field buffer as strings and have them
displayed immediately. This will be necessary if you want to
change a field's value if the field is not the current field being
edited. The FormWriteFieldValue() function does just this. This
function is an alternative to the FormPutFieldData() function.
FormWriteFieldValue()
---------------------
The FormWriteFieldValue() writes a string to the field's input
buffer and displays the changes immediately. Here is the
prototype:
int FormWriteFieldValue(FORMPTR form, int entrynum, char *value)
The first and second arguments are the form and the field entry
number, respectively.
The third argument is the pointer to the string of characters to
write to the string buffer. The length of the string cannot exceed
the length of the field's input buffer. If you do not know the
length of the field buffer, you can use the FIELD_BUFSIZE() macro.
#include "cwlform.h"
main()
{
/*... Assume initializations are done ... */
FormWriteFieldValue(form,1,"45");
}
This writes a string "45" to the field's input buffer and displays
"45" on the form (if the field's position is visible on the
screen).
If there are no errors, FormWriteFieldValue() returns NO_ERROR.
If there are errors, FormWriteFieldValue() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 60 The C Data Forms Library Page 60
SETTING FIELD PRE-FUNCTIONS
---------------------------
The C Data Forms Library's form manager allows functions to be
called prior to inputting a field. This function is not limited to
just 'call a function and return to inputting' type of a function
that you may find in some other commercial or shareware function
libraries. The pre functions in The C Data Forms Library have the
added power of telling the form manager what to do next i.e. edit
the current field, go to some other field, exit the form, etc.
There are two ways of setting up a pre-input function. One way is
to define a global function that will be called for every field in
every form defined. The second way is to define a pre-input
function for each individual field in a particular form.
Defining a global pre-functions
-------------------------------
You can define a function that will be performed prior to inputting
of every field in any form defined. The global_field_prefunc
function pointer points to this function. Here is the prototype:
int (*global_field_prefunc)(FORMPTR form, int *entrynum)
The first argument is the pointer to the current active form.
The second argument is a pointer to an integer that represents the
current field number being edited. The reason for a pointer and
not the actual value will become apparent later on.
Defining a field specific pre-input functions
---------------------------------------------
The FormSetFieldPreFunction() defines a pre-input function for a
particular field in a form. Here is the prototype:
int FormSetFieldPreFunction(FORMPTR form, int entrynum,
int (*prefunc)(FORMPTR form, ]
int *entry))
The first argument is the pointer to the form, and the second the
field number to assign the function to.
The third argument is a pointer to the function that returns an
integer. The arguments to this function are the same as the
global_field_prefunc function pointer defined above.
Page 61 The C Data Forms Library Page 61
Return Values to the Form Manager
---------------------------------
The global_field_prefunc and the function defined in the
FormSetFieldPreFunction() MUST return a value back to the form
manager. This return value tells the form manager what to do next.
Here is a list of the valid return values:
Option Definition
------ ----------
FIELD_PREVFIELD Move input cursor to the previous field
in the form and start editing from there.
FIELD_NEXTFIELD Move input cursor to the next field in
the form and continue editing the next
field.
FIELD_CONTINUE_PROCESS Edit the input for the current field.
FIELD_PROCESS_DATA Process input that was already entered
in the field.
FORM_CLEAR Clear the form and move input cursor to
first available field.
FORM_ACCEPT Accept the current input in the form and
exit.
FIELD_NEWFIELD Move cursor to a new field and continue
editing from there.
FORM_EXIT_CLEAR Clear the form and quit editing.
The FIELD_PREVFIELD return value will move the input cursor to the
previous field in the form. If you try to move beyond the first
available field on the form the FORM_WRAP and/or the
FORM_EXIT_INITIAL form options will take action depending on
whether they are on or off. See CREATING FIELD ENTRIES for a
definition of the FORM_WRAP and FORM_EXIT_INITIAL options.
The FIELD_NEXTFIELD return value will move the input cursor to the
next field in the form. If you try to move beyond the first
available field in the form, the FORM_WRAP form option will take
action depending on whether this option was turned on.
The FIELD_CONTINUE_PROCESS return value will just let the form
manager edit the current field, just as if the pre-input function
was not called.
The FIELD_PROCESS_DATA return value will process whatever data is
residing the field's input buffer, and will not edit the current
field. You can place strings in the field input buffer by calling
the FormWriteFieldValue() function. The FIELD_PROCESS_DATA will
still right or left justify, comma format, etc. whatever is in the
field buffer, just as if it were entered manually (edited).
Page 62 The C Data Forms Library Page 62
The FORM_CLEAR return value clears the form of all input data and
moves the input cursor to the first available field.
The FORM_ACCEPT return value accepts all the input from the input
fields and exits. The form is not exited automatically if the
FORM_CHECK option is on or if a field in the form has the
FIELD_CHECK option on. See CREATING FIELD ENTRIES for a definition
of the FORM_CHECK and FIELD_CHECK options.
The FIELD_NEWFIELD return value moves the input cursor to the field
assigned to the pointer to the current entry. If you remember, the
pre-function prototype passed a pointer to the current field
number. If you assign a field number to the dereferenced pointer
and the FIELD_NEWFIELD return value is used, the form manager will
move the input cursor to the field desired. If the field entry
does not exist, the form manager will not move the input cursor.
If the field is protected (FIELD_PROTECT flag is on) for the
desired field, the input cursor is not moved.
The FORM_EXIT_CLEAR clears the form of all input and exits the
form. The form is not automatically cleared and exited if there is
an exit function defined for the form. Form exit functions are
discussed later in the manual.
If both the global_field_prefunc and an entry has a pre-input
function defined via the FormSetFieldPreFunction() function, the
global_field_prefunc is performed first. If the return value from
the global function is FIELD_CONTINUE_PROCESS, then the pre-input
function defined for the field is performed.
#include "cwlform.h"
#include "menu.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NUMPROMPTS 5
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,FIELD_RJUSTIFY,1,REVERSE,"3[0-9]",
STRING, 2, 35, "__________", '_', 0, 10, NO_FIELD_OPTIONS,
1,REVERSE, "10.",
LINTEGER,3, 35, "_________", '_', 2, 12,
FIELD_COMMA|FIELD_ZSUPPRESS2, 1,REVERSE, "9[0-9]",
DOUBLE,4, 20, "_______",'_',1,7, FIELD_COMMA|FIELD_LJUSTIFY,1,
REVERSE,"7[0-9/.]",
CHAR, 5, 20, "_", '_', 1, 1, FIELD_UPPERCASE, 1,REVERSE,
"[YyNn]",
FIELDEND};
FORMPTR form;
WPOINTER w, helpwin;
char *prompt[] = { "Enter an integer:",
"Choose a string:",
"Enter a large integer value:",
"Enter a double:",
"Enter Yes or No (Y/N):"};
Page 63 The C Data Forms Library Page 63
char *help[] = {"Enter a value between 0 and 999",
"Use Up arrow or down arrow to make selection",
"Enter a value between 0 and 2,000,000",
"Enter a value with a decimal point",
"Enter a 'Y' for yes, 'N' for no"};
int display_help();
int get_choice();
int choose_list();
POPUP_MENU_ENTRY popup_entry[] = {"Choice 1",1,0,0,NULLFN,
"Choice 2",2,0,0,NULLFN,
"Choice 3",3,0,0,NULLFN,
"Choice 4",4,0,0,NULLFN,
"Choice 5",5,0,0,NULLFN,
"Choice 6",6,0,0,NULLFN,
"Choice 7",7,0,0,NULLFN,
CWL_NULL,0};
POPUP_MENU_PTR popup;
unsigned menu_colors[NUMPOPUPCOLORS];
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
FormInitializeFloat();
WindowSaveInitial(0);
menu_colors[ENTRYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[BORDERCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
menu_colors[HOTKEYCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,blue);
menu_colors[HIGHLIGHTCOLOR] = CREATE_VIDEO_ATTRIBUTE(cyan,black);
menu_colors[UNAVAILCOLOR] = CREATE_VIDEO_ATTRIBUTE(white,black);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt[i],i+1,1);
/* setup help window */
helpwin = WindowInitialize(NOBORDER,25,1,78,1,REVERSE,REVERSE,0);
WindowOpen(helpwin);
popup = PopupCreateMenu(popup_entry,menu_colors,4,10,7,
NO_POPUP_OPTIONS,WNULLFN,VWNULLFN);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
FormSetListField(form,2,popup);
/* set field pre-func of second field */
FormSetFieldPreFunction(form,2,get_choice);
/* display help window */
WindowDisplay(helpwin, 2, NOEFFECT);
Page 64 The C Data Forms Library Page 64
/* get form info */
FormGetInput(form,1,1);
}
/* Displays help for each field */
int display_help(FORMPTR form, int *entry)
{
/* clear window and display appropriate help */
WindowClear(helpwin);
WindowWriteString(helpwin,help[*entry-1],1,1);
/* return value back to form manager */
return FIELD_CONTINUE_PROCESS;
}
The above example displays a help message for each input field.
Note that the display_help() function returns a
FIELD_CONTINUE_PROCESS to the form manager.
If there are no errors, FormSetFieldPreFunction() returns NO_ERROR.
If there are errors, FormSetFieldPreFunction() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 65 The C Data Forms Library Page 65
SETTING FIELD POST FUNCTIONS
----------------------------
The C Data Forms Library's form manager allows functions to be
called after inputting a field.
There are two ways of setting up a post-input function. One way is
to define a global function that will be called for every field in
every form defined. The second way is to define a post-input
function for each individual field in a particular the form.
Defining a global post-function
-------------------------------
You can define a function that will be performed prior to inputting
of every field in any form defined. The global_field_postfunc
function pointer points to this function. Here is the prototype:
int (*global_field_postfunc)(FORMPTR form, int *entrynum)
The first argument is the pointer to the current active form.
The second argument is a pointer to an integer that represents the
current field number being edited. The reason for a pointer and
not the actual value will become apparent later on.
Defining a field specific post-function
---------------------------------------
The FormSetFieldPostFunction() defines a post-input function for a
particular field in a form. Here is the prototype:
int FormSetFieldPostFunction(FORMPTR form, int entrynum,
int (*postfunc)(FORMPTR form, int *entry))
The first argument is the pointer to the form, and the second the
field number to assign the function to.
The third argument is a pointer to the function that returns an
integer. The arguments to this function are the same as the
global_field_postfunc function pointer defined above.
Return Values to the Form Manager
---------------------------------
The global_field_postfunc and the function defined in the
FormSetFieldPostFunction() MUST return a value back to the form
manager. This return value tells the form manager what to do next.
Here is a list of the valid return values:
Page 66 The C Data Forms Library Page 66
Option Definition
------ ----------
FIELD_PREVFIELD Move input cursor to the previous field
in the form and start editing from there.
FIELD_NEXTFIELD Move input cursor to the next field in
the form and continue editing the next
field.
FIELD_CONTINUE_PROCESS Continue processing the field (display
value entered in field buffer from
previous edit).
FIELD_PROCESS_DATA Same as FIELD_CONTINUE_PROCESS.
FORM_CLEAR Clear the form and move input cursor to
first available field.
FORM_ACCEPT Accept the current input in the form and
exit.
FIELD_NEWFIELD Move cursor to a new field and continue
editing from there.
FORM_EXIT_CLEAR Clear the form and quit editing.
The above return values are the same as the return values for
pre-input function except for the FIELD_CONTINUE_PROCESS and
FIELD_PROCESS_DATA functions. FIELD_CONTINUE_PROCESS just
continues as if no post-input function was called.
FIELD_PROCESS_DATA has the same definition as
FIELD_CONTINUE_PROCESS.
If both the global_field_postfunc and an entry has a post-input
function defined via the FormSetFieldPostFunction() function, the
global_field_postfunc is performed first. If the return value from
the global function is FIELD_CONTINUE_PROCESS, then the post-input
function defined for the field is performed.
Here is an example of using the post-input functions:
#include <stdio.h>
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NUMPROMPTS 3
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,FIELD_RJUSTIFY,1,REVERSE,"3[0-9]",
INTEGER,2,35,"___",'_',1,3,FIELD_RJUSTIFY,1,REVERSE,"3[0-9]",
INTEGER,3,35,"___",'_',1,3,FIELD_RJUSTIFY,1,REVERSE,"3[0-9]",
INTEGER,4,35,"___",'_',1,3,FIELD_RJUSTIFY,1,REVERSE,"3[0-9]",
INTEGER,5,35,"____",'_',1,4,FIELD_RJUSTIFY|FIELD_PROTECT,1,
REVERSE,"4[0-9]",
FIELDEND};
Page 67 The C Data Forms Library Page 67
FORMPTR form;
WPOINTER w, helpwin;
char *prompt = "Enter a number between 0 and 999:";
char *totstr = "Current Total :";
int display_total();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* write prompts to the form window */
for (i=0;i<=NUMPROMPTS;i++)
WindowWriteString(w,prompt,i+1,1);
WindowWriteString(w,totstr,5,1);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* set global post-function */
global_field_postfunc = display_total;
/* get form info */
FormGetInput(form,1,1);
}
/* call total function */
int display_total(FORMPTR form, int *entry)
{
int i,total=0,num;
for (i=1;i<=4;i++)
{
FormGetFieldData(form,i,&num);
total+=num;
}
FormPutFieldData(form,5,total);
return FIELD_CONTINUE_PROCESS;
}
The above example displays a running total of four input fields.
The total is displayed in the fifth input field. Note the return
value of FIELD_CONTINUE_PROCESS, which informs the form manager to
carry on as if no post-input function had been call.
If there are no errors, FormSetFieldPostFunction() returns
NO_ERROR.
If there are errors, FormSetFieldPostFunction() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist.
Page 68 The C Data Forms Library Page 68
UNDEFINED KEYSTROKE PROCESSING
------------------------------
Another powerful feature of the form library is that you can call a
function for keys that are not in the current key definitions. For
instance, say you want the Tab key and the down arrow to mean
accept the input and go to the next field. Since there is only
room for one definition for accept input, you can write a function
that checks for the Tab key, and return a value to the form manager
as to what action to take.
The form_undef_fkey_func and form_undef_akey_func function pointers
-------------------------------------------------------------------
There are two global variables, form_undef_fkey_func and
form_undef_akey_func. These two variables are pointers to
functions that return an integer. By setting these functions to
point to your own functions, you can process undefined keystrokes
yourself and return to the form manager what action to take.
The form_undef_fkey_func is used to define keys that are not normal
ASCII keys. For instance, Control key and Alt key combinations,
the F-keys, PgDn and PgUp, etc. The form_undef_akey_func is used
to define normal ASCII keys (keys with ASCII values between 32 and
255, inclusive).
Whenever an undefined key is encountered, the form manager will
pass the current FORMPTR, current field entry (as an integer), the
string that has been currently entered, the current key pressed,
and the current position number of the character being processed to
your function. The prototype for this function is as follows:
int (*form_undef_fkey_func)(FORMPTR form, /* current form */
int entry, /* current field */
char *str,/* string currently entered */
int key, /* key that was pressed */
int *pos) /* position number of current
character being processed */
The prototype to the form_undef_akey_func is similar to the one
above. The str is a pointer to a null-terminated string of
characters that has been currently entered. For instance, if the
string currently entered is
ABC123
str will point to "ABC123". The key value is the key that was
pressed. You should use the values defined in the header file
"keycodes.h" if you want to check for non-ascii keys. This will
ensure that you are properly checking the keystroke desired. For
instance, if you want to check if the key pressed was the Page Up
key, use the constant PGUP defined in keycodes.h.
The pos argument is a pointer to an integer that denotes the number
of the current character that the cursor is on. The first
Page 69 The C Data Forms Library Page 69
character is at position number 0, the second character in the
input field is 1, etc. If there is an input mask the position
number does not include any characters that are used to create the
non-input positions. For instance:
"__/__/__ "
01 23 45
The numbers under the mask are the position numbers for each
character. The reason why the pos argument is a pointer, and not a
regular integer will be defined later.
Specifying when to call an undefined key function in a Regular
Expression
----------
An empty bracketed simple regular expression tells the form manager
to call the undefined keystroke function. An example of this type
of regular expression is as follows:
Regular Definition
Expression ----------
----------
[A-Z][] The first input position must be
between 'A' and 'Z', and the second
position will automatically call
the user defined undefined
keystroke function.
20[] All twenty input positions will
call the undefined keystroke
function.
3[0-9]2[]2[A-Z] The first three input positions
must be between '0' and '9', the
next two input positions
automatically call the undefined
keystroke function, and the last two
positions must be between 'A' and 'Z'.
If you use this form of a regular expression, you MUST have defined
an undefined keystroke function. If you did not define one, you
will more than likely get into an infinite loop. Using this form
of regular expression combined with the return values (defined
below) that can be returned to the input manager, you will
virtually have total control of the way the input is handled.
Return Values To The Form Manager
---------------------------------
When writing your function you must return an integer to the form
manager. This integer will inform the form manager as to what
action to take. Here are a list of the return values and what they
inform the form manager:
Page 70 The C Data Forms Library Page 70
Return Action to
Value Take
------ ---------
FIELD_CONTINUE Do not Process keystroke and continue
getting input.
FIELD_MOVELEFT Move cursor left in field.
FIELD_MOVERIGHT Move cursor right in field.
FIELD_DELNOMOVE Delete character at cursor.
FIELD_INSTOGGLE Toggle Insert/Overwrite mode.
FIELD_BACKSPACE Destructive Backspace.
FIELD_ACCEPT Accept Input and go to next field.
FIELD_ACCEPTDEFAULT Accept default field string and return.
FIELD_ERASEINPUT Erase Input and go to first character in
the field.
FIELD_GOTOFIRST Go to first input character in field.
FIELD_GOTOLAST Move cursor to last input character in
field.
FIELD_INSERTCHAR Accept character as valid and insert it at
the current cursor position.
FIELD_NEXTFIELD Accept input and go to the next field in
the form.
FIELD_PREVFIELD Accept input and go to the previous field.
FORM_ACCEPT Accept all input in the form and exit form.
FORM_CLEAR Clear the form and move input to first
available field entry.
FORM_EXIT_CLEAR Clear the form and quit editing.
FIELD_MOVE_TO_CHARACTER Move cursor to input position specified
in the *pos argument.
The FIELD_MOVE_TO_CHARACTER return value moves the input cursor to
the position in the input string specified in the fourth argument
of form_undef_akey_func or form_undef_fkey_func. If you recall,
the fourth argument was a pointer to an integer. You can assign a
value to the *pos argument in your user defined function, and then
return a FIELD_MOVE_TO_CHARACTER return code to move the input
cursor to the desired input position.
Page 71 The C Data Forms Library Page 71
These user-defined functions can do anything, not just process
keystrokes. For instance, if you want F1 to be a help key, where
the help function is in a function called do_help() you must make
sure that:
a) the F1 key is undefined (not defined in the form_edit_key array)
b) the form_undef_fkey_func function pointer points to your
function c) return an integer to the form manager from your
function.
Here is a typical way that this would be set up:
#include "window.h"
/* ... Other #includes and #defines */
int do_help(); /* define help function */
main()
{
WindowInitializeSystem();
FormInitializeSystem();
/* ...Some code */
form_undef_fkey_func = do_help; /* point function pointer
to do_help */
FormGetInput(/* ... Parameters */); /* call input
function */
/* ... Other code */
}
int do_help(FORMPTR form, int entry, char *str, int ch, int pos)
{
if (ch == F1) /* check for F1 */
{
/* help function goes here */
}
return FIELD_DONT_PROCESS; /* make sure form manager does not
process this or any other undefined
keystroke */
}
With this flexibility in the input functions, you can totally
control how input is handled.
Page 72 The C Data Forms Library Page 72
PROCESSING EDITING ERRORS
-------------------------
There are two categories of errors that The C Data Forms Library
checks for when editing a field in a form. The first category
includes checking to see if enough characters have been entered
into the field and to make sure the input matches the regular
expression.
The second category are errors that occur when the field is checked
to see if the data entered falls in a valid range, the name entered
is found in a database of some type, etc. namely the errors that
The C Data Forms Library cannot check for internally, only you (the
programmer) knows whether the data entered is valid.
This section deals with the first category of errors.
Minimum Number of Characters Error Checking
-------------------------------------------
The C Data Forms Library internally checks to see if the number of
characters entered manually into a field (not data written to the
field using the FormWriteFieldValue() function) is enough to
satisfy the minimum number of characters that must be entered for
the field. As stated before, the minimum number of characters
expected is initialized in the FIELD_ENTRY structure.
Overriding Error Checking for Minimum number of characters
----------------------------------------------------------
You can override checking the number of characters entered by
turning on one or both of the override options,
FIELD_OVERRIDE_FORWARD and FIELD_OVERRIDE_BACKWARD. The
FIELD_OVERRIDE_FORWARD overrides checking when the field is exited
with a forward (toward the last field in the form) advance. The
FIELD_OVERRIDE_BACKWARD overrides checking when the field is exited
with a backward advance (toward the first field in the form). As
stated in previous sections, FormSetFieldOptions() turns on or
turns off field options. Some useful purposes of overriding the
number of characters entered error checking is to allow the user to
move to a previous field so that it can be changed, without having
to enter some data in the current field. Here is an example of
using this technique with the FIELD_OVERRIDE_BACKWARD option.
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define NUMPROMPTS 8
Page 73 The C Data Forms Library Page 73
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,2,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,3,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,4,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,5,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,6,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,7,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
INTEGER,8,35,"___",'_',1,3,FIELD_OVERRIDE_BACKWARD,1,REVERSE,
"3[0-9]",
FIELDEND};
FORMPTR form;
WPOINTER w;
char *prompt = "Enter a number :";
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i+1,1);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* get form info */
FormGetInput(form,1,1);
}
The example above allows the user to edit a previous field even
though the field may not contain any characters. The
FIELD_OVERRIDE_BACKWARD option allows us to override the minimum
number of characters error check.
Checking if Field Characters Match Regular Expression
-----------------------------------------------------
Another check that is done internally is to see if each character
entered matches the corresponding regular expression character.
Page 74 The C Data Forms Library Page 74
This check is only done automatically if the FIELD_CHECKREGEXP or
FIELD_CHECKREGEXP_IGNORECASE options are turned on. The way these
two options work are exactly the same as the CHECKREGEXP and
CHECKREGEXP_IGNORECASE options work for single input fields in the
WindowGet...() family of functions. See page XX for more details
on these options.
Calling a User Written Function when errors occur
-------------------------------------------------
You can set up a function that will be called if any of the fields
fail the minimum number of entered characters test or the regular
expression error test by pointing the field_edit_error_func
function pointer to a user-written function. Here is the prototype
to this function pointer:
int (*field_edit_error_func)(FORMPTR form, int entrynum,
int errtype, char *str, int errval)
The first argument is a pointer to the form of where the error
occurred.
The second argument is the number of the offending field entry.
The third argument is the type of error that occurred. If the
error occurred because the minimum number of characters were not
entered, this value is the constant FIELD_MINCHARS_ERROR. If the
error was caused because the input conflicts with the regular
expression, this value is the constant FIELD_REGEXP_ERROR.
The fourth argument is the string that was entered in the field.
The fifth argument depends on the type of error. If the error is a
FIELD_MINCHARS_ERROR error, this value is the minimum number of
characters expected. If the error is a FIELD_REGEXP_ERROR error
this value is the position in string that does not match the
regular expression. Position numbers in the string start from 0.
Return Values for User Written Function
---------------------------------------
You MUST return a value back to the form manager if your
user-defined error function is called. There are two possible
return values, FIELD_ERROR and FIELD_ACCEPT. FIELD_ERROR tells the
form manager to edit the field again i.e. let the user correct
his/her error. The FIELD_ACCEPT return value accepts the input,
even though there is an error.
Here is an example:
#include <stdio.h>
#include "cwlform.h"
Page 75 The C Data Forms Library Page 75
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define WHITEONRED CREATE_VIDEO_ATTRIBUTE(RED_,WHITE_)
#define NUMPROMPTS 8
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,2,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,3,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,4,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,5,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,6,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,7,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,8,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
FIELDEND};
FORMPTR form;
WPOINTER w, error_win;
char *prompt = "Enter a number :";
int display_error();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
error_win =
WindowInitialize(BORDER,1,1,78,22,WHITEONRED,WHITEONRED,
SINGLEBOX);
WindowOpen(error_win);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i+1,1);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* initialize error function */
field_edit_error_func = display_error;
/* get form info */
FormGetInput(form,1,1);
}
Page 76 The C Data Forms Library Page 76
/* This is called if there is an editing error */
int display_error(FORMPTR form, int entry, int errval,
char *str, int pos)
{
char buf[80];
WindowClear(error_win);
switch (errval)
{
case FIELD_MINCHARS_ERROR: /* not enough characters */
sprintf(buf,
"You must enter at least %d characters in this field",pos);
break;
case FIELD_REGEXP_ERROR: /* regular expression error */
sprintf(buf,"Invalid character entered in position %d",pos);
break;
}
/* display window and return to form manager */
WindowWriteCenterString(w,buf,3);
WindowWriteCenterString(error_win,
"Press Any Key to Continue...",5);
WindowDisplay(error_win,1,EXPLODE);
MakeSound(300,500);
GET_KEY();
WindowHide(error_window,CONTRACT);
return FIELD_ERROR;
}
If the field_edit_error_func points to a NULLFN, no function is
called.
Page 77 The C Data Forms Library Page 77
USER DEFINED ERROR CHECKING
---------------------------
This section discusses the way to have a user-defined error
checking function. This function checks errors that The C Data
Forms Library could not possibly do internally. This includes
checking the input for valid names, passwords, etc.
The FormSetFieldValidateFunction() function
-------------------------------------------
The FormSetFieldValidateFunction() allows the programmer to assign
a validation function to a field. Here is the prototype:
int FormSetFieldValidateFunction(FORMPTR form, int entrynum,
int (*func)(FORMPTR cform,
int centry,
char *str))
The first argument is the pointer to a form. The second argument
is the entry number to assign the function to.
The third argument is a pointer to the user-defined function. This
function should allow three arguments. The first and second are
the pointer to the form, and the field entry number. The last
argument is the string entered in the field.
Return Values for the user defined error function
-------------------------------------------------
You MUST return a value back to the form manager if your
user-defined validation function is called. There are two possible
return values, FIELD_ERROR and FIELD_ACCEPT. FIELD_ERROR tells the
form manager that there was an error, and to edit the field again
i.e. let the user correct his/her error. The FIELD_ACCEPT return
value accepts the input as valid.
#include <stdio.h>
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define WHITEONRED CREATE_VIDEO_ATTRIBUTE(RED_,WHITE_)
#define NUMPROMPTS 8
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,2,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,3,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,4,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,5,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,6,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,7,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,8,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
FIELDEND};
Page 78 The C Data Forms Library Page 78
FORMPTR form;
WPOINTER w, error_win;
char *prompt = "Enter a number :";
int display_error();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
error_win =
WindowInitialize(BORDER,10,1,78,8,WHITEONRED,WHITEONRED,
SINGLEBOX);
WindowOpen(error_win);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i+1,1);
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* initialize validation function */
for (i=1;i<=NUMPROMPTS;i++)
FormSetFieldValidateFunction(form,i,check_range);
/* get form info */
FormGetInput(form,1,1);
}
/* This is called to check the range */
int check_range(FORMPTR form, int entry, char *str)
{
int num;
WindowClear(error_win);
num = atoi(str);
/* check and display error window if out of range */
if (num < 1 || num > 500)
{
WindowPrintf(error_win,
"The number entered %s, must be between %d and %d",
str,LOWLIM,HILIM);
WindowWriteCenterString(error_win,
"Press Any Key to Continue...",5);
WindowDisplay(error_win,1,EXPLODE);
MakeSound(300,500);
Page 79 The C Data Forms Library Page 79
GET_KEY();
WindowHide(error_win,CONTRACT);
/* re-edit this field */
return FIELD_ERROR;
}
else
/* field OK */
return FIELD_ACCEPT;
}
The above example tests each field to make sure the input falls
between 1 and 500. If not, an error window is displayed and
FIELD_ERROR is returned to the form manager. If the field is in
range, FIELD_ACCEPT is returned to the form manager.
There is a better way to check if a field is included in a range of
values. This will be discussed later in the FormCheckFieldRange()
function.
If there are no errors, FormSetFieldValidateFunction() returns
NO_ERROR.
If there are errors, FormSetFieldValidateFunction() returns one of
the following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
FormCheckFieldRange()
---------------------
The FormCheckFieldRange() checks if a field's input falls within
the range of two values. These values can be any data type, except
doubles (doubles are handled with a separate function).
Here is the prototype:
int FormCheckFieldRange(FORMPTR form, int entrynum, int
options, ...)
Note the last argument. The prototype suggests that the argument
is optional, but not really. The '...' means that there are two
values expected. The first value is the lower limit, and the
second value is the upper limit. These values can be of any simple
data type, (char, int, unsigned, etc.) as well as two string.
The first two arguments are the pointer to the form and the field
entry number, respectively. The third arguments are range options
to use. Here are the list of range options:
Page 80 The C Data Forms Library Page 80
Range Option Definition
------------ ----------
INCLUDE_LOW Includes the lower limit as valid.
INCLUDE_HIGH Includes the upper limit as valid.
EXCLUDE_LOW Excludes the lower limit as valid.
EXCLUDE_HIGH Excludes the upper limit as valid.
NO_RANGE_OPT No range options (use default).
INCLUDE_LOW includes the lower limit in the range check as being a
valid number.
INCLUDE_HIGH includes the upper limit in the range check as being a
valid number.
EXCLUDE_LOW does not accept any value that is equivalent to the
lower limit.
EXCLUDE_HIGH does not accept any value that is equivalent to the
upper limit.
NO_RANGE_OPT uses the default (INCLUDE_LOW | INCLUDE_HIGH).
Note that the bitwise OR (|) can be used to combine options.
INCLUDE... options override EXCLUDE... options if they are both
used simultaneously.
Here are a few examples of using FormCheckFieldRange():
a) FormCheckFieldRange(form,1,NO_RANGE_OPT,100,200)
b) FormCheckFieldRange(form,1,NO_RANGE_OPT,-1, 50)
c) FormCheckFieldRange(form,3,EXCLUDE_LOW,'a','z')
d) FormCheckFieldRange(form,2,NO_RANGE_OPT,"abc","def");
a) Tests if the value entered in field 1 is between 100 and 200,
inclusive.
b) Tests if the value entered in field 1 is between -1 and 50,
inclusive.
c) Tests if the single value entered in field 1 is
between 'a' and 'z', but not including 'a'.
d) Tests if the string entered is between "abc" and "def"
inclusive.
When the test is made, a value is returned that tells how the test
turned out.
Value returned Definition
-------------- ----------
FIELD_LOW Field value is too small.
FIELD_HIGH Field value is too large.
FIELD_OUT_OF_RANGE Field is either too small or too
large.
FIELD_OK Field is in range.
Page 81 The C Data Forms Library Page 81
If there are no errors, FormCheckFieldRange() returns one of the
values above.
If there are errors other than the ones mentioned above,
FormCheckFieldRange() returns one of the following and sets
window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
Page 82 The C Data Forms Library Page 82
CLEARING A FORM
---------------
FormClear()
-----------
You can clear a form of all input and move the input cursor to any
field using the FormClear() function. Here is the prototype:
int FormClear(FORMPTR form, int entry)
The first argument is the pointer to the form, and the second
argument is the entry to place the input cursor when the form is
cleared. If the entry is protected, the form manager tries to find
the next available field. The number of characters that is cleared
is determined by the visible width of the input field.
If there is no error, FormClear() returns NO_ERROR.
If there are errors FormClear() returns the following and sets
window_error_code to this value:
UNDEFINED_FORM if the FORMPTR does not exist.
Page 83 The C Data Forms Library Page 83
EXITING A FORM
--------------
When the last input field is edited, or the form is exited
prematurely, an exit function can be called before the form is
actually closed.
FormSetExitFunction()
---------------------
The FormSetExitFunction() sets up a function that will be called
whenever a form is exited. Here is the prototype:
int FormSetExitFunction (FORMPTR form,
int (*exit_func)(FORMPTR cform,
int status,
int *currfield))
The first argument is the pointer to the form. The second argument
is the pointer to a user-defined exit function. This function is
passed three arguments from the form manager.
The first argument is the current form. The second argument is a
status indicator that tells how the form was exited (last field was
exited, first field was exited etc.). Here are the list of status
codes:
Status Code Definition
----------- ----------
FIRST_FIELD_EXIT Form was exited by moving the input
cursor to a field before the first
available field in a form.
LAST_FIELD_EXIT Form was exited by moving the input
cursor to a field after the last
available field.
FORM_END Form exited and saved by other means
i.e. an accept key was hit in the
middle of the form.
FORM_END_CLEAR Form exited and potentially cleared
in the middle of the form.
The third argument is a pointer to an entry number.
The user-defined exit function MUST return a value back to the form
manager. Here is a list of the valid return values:
FORM_ACCEPT - End input of the form.
FORM_REEDIT - Reedit the form starting at the entry number assigned
to the pointer *currfield.
The FORM_END value ends the processing of the fields.
Page 84 The C Data Forms Library Page 84
The FORM_REEDIT value tells the form manager to collect input again
in the form, but start at the number assigned to *currfield.
#include <stdio.h>
#include "cwlform.h"
#define NORM CREATE_VIDEO_ATTRIBUTE(BLACK_,WHITE_)
#define REVERSE CREATE_VIDEO_ATTRIBUTE(WHITE_,BLACK_)
#define WHITEONRED CREATE_VIDEO_ATTRIBUTE(RED_,WHITE_)
#define NUMPROMPTS 8
#define LOWLIM 1
#define HILIM 200
FIELD_ENTRY field_array[] =
{INTEGER,1,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,2,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,3,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,4,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,5,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,6,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,7,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
INTEGER,8,35,"___",'_',1,3,NO_FIELD_OPTIONS,1,REVERSE,"3[0-9]",
FIELDEND};
FORMPTR form;
WPOINTER w, error_win, again_win;
char *prompt = "Enter a number :";
int check_range();
int edit_again();
main()
{
int i;
WindowInitializeSystem();
FormInitializeSystem();
WindowSaveInitial(0);
w = WindowInitialize(BORDER,1,1,78,22,NORM,NORM,SINGLEBOX);
WindowOpen(w);
error_win =
WindowInitialize(BORDER,10,1,78,10,WHITEONRED,WHITEONRED,
SINGLEBOX);
WindowOpen(error_win);
again_win =
WindowInitialize(NOBORDER,25,1,80,1,REVERSE,REVERSE,0);
WindowOpen(again_win);
WindowWriteString(again_win,
"Enter a field to edit or ENTER to exit the form",1,1);
/* write prompts to the form window */
for (i=0;i<NUMPROMPTS;i++)
WindowWriteString(w,prompt,i+1,1);
Page 85 The C Data Forms Library Page 85
/* initialize form */
form = FormInitialize(w,field_array,FORM_HIGHLIGHT);
/* initialize exit function */
FormSetExitFunction(form,edit_again);
FormSetFieldOptions(form,1,FIELD_PROTECT,1);
/* initialize validation function */
for (i=1;i<=NUMPROMPTS;i++)
FormSetFieldValidateFunction(form,i,check_range);
/* get form info */
FormGetInput(form,1,1);
}
/* This is called if there is an editing error */
int check_range(FORMPTR form, int entry, char *str)
{
int num;
WindowClear(error_win);
num = atoi(str);
/* check and display error window if out of range */
if (num < LOWLIM || num > HILIM)
{
WindowPrintf(error_win,"The number entered %s is out of range\n"
"The number must be between %d and %d",
str,LOWLIM,HILIM);
WindowWriteCenterString(error_win,
"Press Any Key to Continue...",5);
WindowDisplay(error_win,1,EXPLODE);
MakeSound(300,500);
GET_KEY();
WindowHide(error_win,CONTRACT);
/* re-edit this field */
return FIELD_ERROR;
}
else
/* field OK */
return FIELD_ACCEPT;
}
/* ask user whether they want to re-edit the form */
int edit_again(FORMPTR form, int status, int *entry)
{
char buf[3];
int num;
buf[0] = 0;
WindowDisplay(again_win,1,NOEFFECT);
Page 86 The C Data Forms Library Page 86
/* loop until user has a viable entry or hits return */
do
{
WindowGetString(again_win,1,50,buf,'_',0,2,NO_OPTIONS,1,
"2[0-9]");
num = atoi(buf);
} while (!((num >= 1 && num <= NUMPROMPTS) || buf[0] == 0));
WindowHide(again_win,NOEFFECT);
/* return hit, so quit */
if (buf[0] == 0)
return FORM_END;
else
{
/* assign entry number and return */
*entry = num;
return FORM_REEDIT;
}
}
The example above makes use of the exit function by asking the user
whether he/she wants to edit another field. If the field number
entered is in range, edit_again() returns a FORM_REEDIT to the form
manager, as well as assigns the appropriate field number.
If the field number that is assigned to *entry is out of bounds,
the form manager will always start editing input from the first
available field.
If there is no error, FormSetExitFunction() returns NO_ERROR.
If there are errors FormSetExitFunction() returns the following and
sets window_error_code to this value:
UNDEFINED_FORM if the FORMPTR does not exist.
Page 87 The C Data Forms Library Page 87
DISPOSING OF A FORM
-------------------
If a form is no longer needed, all memory allocated to the form
should be returned to the heap.
FormFree()
----------
The FormFree() function deallocates all memory allocated to the
form, and makes the FORMPTR invalid. Here is the prototype:
int FormFree(FORMPTR form)
The only argument is the pointer to the form. Once this function
is called, the FORMPTR cannot be used unless it is assigned to a
valid form.
If there is no error, FormFree() returns NO_ERROR.
If there are errors FormFree() returns the following and sets
window_error_code to this value:
UNDEFINED_FORM if the FORMPTR does not exist.
Page 88 The C Data Forms Library Page 88
MISCELLANEOUS FORM FUNCTIONS
----------------------------
FormGetFieldString()
--------------------
The FormGetFieldString() returns the input entered in the field
buffer. Here is the prototype:
int FormGetFieldString(FORMPTR form, int entry, char *buffer)
The first two arguments are the FORMPTR and field entry number.
The third argument is the pointer to a buffer that the field data
will be copied to. The buffer must be large enough to hold the
string plus 1 for the null byte.
If there is no error, FormGetFieldString() returns NO_ERROR.
If there are errors, FormGetFieldString() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
FormGetFieldRowCol()
--------------------
The FormGetFieldRowCol() function returns the coordinates of a
field in a viewport. This function is useful if you have a virtual
form, and want to know where the field is located in the viewport,
and not the virtual window. Here is the prototype:
int FormGetFieldRowCol(FORMPTR form, int entry, unsigned *row,
unsigned *col)
The *row and *col arguments are pointers to integers that will
store the row and column of the field, respectively.
Since virtual forms can scroll left, right, up, or down, depending
on where the field is, this function can be useful to pinpoint
where the field is located in the viewport. If the form is a
simple windowed form, *row and *col will just contain the row and
column of the field when initialized.
If there is no error, FormGetFieldRowCol() returns NO_ERROR.
If there are errors, FormGetFieldRowCol() returns one of the
following and sets window_error_code to one these values:
UNDEFINED_FORM if the FORMPTR does not exist.
UNDEFINED_FIELD if the field entry does not exist
FIELD_NOT_IN_VIEW if the field is not currently displayed in the
viewport. If this error occurs, *row and *col are invalid and
should not be used.
Page 89 The C Data Forms Library Page 89
FORM MACROS
-----------
Most of these macros use individual FIELD_ENTRY's as an argument.
You should use the GET_FIELD_FROM_FORM() macro to get individual
field entries from a form. An example will follow the first two
macro definitions to illustrate how to get an individual
FIELD_ENTRY.
GET_FIELD_FROM_FORM(form,entry) - returns the FIELD_ENTRY for a
form. This macro simplifies
getting individual FIELD_ENTRY's
from an array of field entries.
FIELD_PROTECT_ON(entry) - returns 1 if the FIELD_ENTRY
entry has the FIELD_PROTECT option
on, 0 otherwise.
Example:
FIELD_ENTRY fields[] = { /* ... List of field entries ... */};
/* other stuff */
FORMPTR form;
main()
{
int is_on;
FIELD_ENTRY fe;
.
.
.
/* Here is one way to get the third FIELD_ENTRY in the
fields array */
fe = fields[2]; /* Gets the third field entry in array fields */
is_on = FIELD_PROTECT_ON(fe);
/* Here is another way to get the third field entry, given that the
form exists and it was initialized with the fields array */
fe = GET_FIELD_FROM_FORM(form,3);
is_on = FIELD_PROTECT_ON(fe);
}
Page 90 The C Data Forms Library Page 90
Remember when accessing FIELD_ENTRY's directly from the array, the
first FIELD_ENTRY is 0, the second is FIELD_ENTRY 1, etc. However,
when using a few of the macros that allow a pointer to a form and
an entry number, entries are numbered from 1 to the highest entry.
FIELD_COMMA_ON(entry) - returns 1 if the FIELD_ENTRY entry has the
FIELD_COMMA option on, 0 otherwise.
FIELD_RJUSTIFY_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_RJUSTIFY option on, 0 otherwise.
FIELD_LJUSTIFY_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_LJUSTIFY option on, 0 otherwise.
FIELD_UPPERCASE_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_UPPERCASE option on, 0 otherwise.
FIELD_LOWERCASE_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_LOWERCASE option on, 0 otherwise.
FIELD_CHECKSPACES_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_CHECKSPACES option on, 0
otherwise.
FIELD_ENHANCEDKEY_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_ENHANCEDKEY option on, 0
otherwise.
FIELD_CHECKREGEXP_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_CHECKREGEXP option on, 0
otherwise.
FIELD_AUTORETURN_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_AUTORETURN option on, 0
otherwise.
FIELD_CHECKREGEXP_IGNORECASE_ON(entry) - returns 1 if the
FIELD_ENTRY entry has the
FIELD_CHECKREGEXP_IGNORECASE option on, 0 otherwise.
FIELD_FLUSHBUFFER_ON(entry) - returns 1 if the FIELD_ENTRY entry
has the FIELD_FLUSHBUFFER option on, 0
otherwise.
FIELD_HOMECURSOR_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_HOMECURSOR option on, 0
otherwise.
FIELD_ZSUPPRESS1_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_ZSUPPRESS1 option on, 0
otherwise.
FIELD_ZSUPPRESS2_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_ZSUPPRESS2 option on, 0
otherwise.
Page 91 The C Data Forms Library Page 91
FIELD_PASSWORD_ON(entry) - returns 1 if the FIELD_ENTRY entry has
the FIELD_PASSWORD option on, 0 otherwise.
FIELD_OVERRIDE_FORWARD_ON(entry) - returns 1 if the FIELD_ENTRY
entry has the
FIELD_OVERRIDE_FORWARD option on, 0
otherwise.
FIELD_OVERRIDE_BACKWARD_ON(entry) - returns 1 if the FIELD_ENTRY
entry has the
FIELD_OVERRIDE_BACKWARD option on,
0 otherwise.
FIELD_CLEARFIELD_ON(entry) - returns 1 if the FIELD_ENTRY entry
will be cleared if the first key
hit in this field is a key
recognized by the field's regular
expression.
FORM_DIRECTION(form) -
returns FORM_FORWARD if the user is moving the input cursor
towards the last field in the form, FORM_BACKWARD if the
user is moving the form input cursor toward the first
field. If the FORM_WRAP option is on, FORM_DIRECTION()
does not change if the form has wrapped to the first or
last available field.
This macro is useful if you want to invoke a pre or post-input
function only if the user is moving toward the last field and not
if they are going toward the first field.
FORM_EXPLODE_TYPE(form) - returns what type of special effect will
be used when the form window is displayed
or hidden. You can also assign values to
this macro. The default value is NOEFFECT.
Example: FORM_EXPLODE_TYPE(form) = EXPLODE;
FORM_WRAP_ON(form) - returns 1 if the FORM_WRAP option is on, 0
otherwise.
FORM_CHECK_ON(form) - returns 1 if the FORM_CHECK option is on, 0
otherwise.
FORM_EXIT_INITIAL_ON(form) - returns 1 if the FORM_EXIT_INITIAL
option is on, 0 otherwise.
FORM_HIGHLIGHT_ON(form) - returns 1 if the FORM_HIGHLIGHT option is
on, 0 otherwise.
FORM_VIRTUAL_ON(form) - returns 1 if the form is a virtual form, 0
otherwise.
FORM_NOEXIT_LAST_ON(form) - returns 1 if the FORM_NOEXIT_LAST
option is on, 0 otherwise.
Page 92 The C Data Forms Library Page 92
FORM_STATIC_ON(form) - returns 1 if the FORM_STATIC option is on, 0
otherwise.
FORM_WINDOW(form) - returns the pointer (WPOINTER) to the form's
window.
FORM_VIRTUAL_WINDOW(form) - returns the pointer (VWPOINTER) to the
form's virtual window.
FORM_NUMBER_OF_FIELDS(form) - returns an integer which is the
number of fields in a form.
FIELD_IN_RANGE(form,entry) - returns 1 if the entry number exists
in a form, 0 otherwise.
FIELD_ROW(entry) - returns an integer which is the row of the
FIELD_ENTRY entry.
FIELD_COLUMN(entry) - returns an integer which is the column of the
FIELD_ENTRY entry.
FIELD_TYPE(entry) - returns an integer denoting the field type of a
FIELD_ENTRY (i.e. INTEGER, STRING, etc.)
FIELD_MASK(entry) - returns a pointer (char *) to the mask string
used for a FIELD_ENTRY.
FIELD_FILL(entry) - returns an integer that denotes the fill
character used for a FIELD_ENTRY.
FIELD_MINIMUM(entry) - returns an integer which denotes the minimum
number of characters needed to be filled in
for a FIELD_ENTRY.
FIELD_VISIBLE_WIDTH(entry) - returns an integer which is the
visible width of a FIELD_ENTRY.
FIELD_REGEXP(entry) - returns a pointer (char *) to the regular
expression string used in a FIELD_ENTRY
entry.
FIELD_ATTRIBUTE(entry) - returns an integer which denotes the
attribute used for the FIELD_ENTRY entry.
FIELD_VARPTR(entry) - returns a pointer (void *) to the user's
variable that will hold the converted data
of the FIELD_ENTRY entry.
FIELD_CHANGE(form,entry) - returns 1 if the data entered in the
field defined by entry has been changed
since editing the form, 0 otherwise. If
the form is re-edited with another call
to FormGetInput(), FIELD_CHANGE() is
reset to 0 for all fields in the form.
Page 93 The C Data Forms Library Page 93
FORM_CHANGE(form) - returns 1 if any fields in the form have
changed, 0 otherwise. If the form is
re-edited with another call to
FormGetInput(), FORM_CHANGE() returns 0.
Page 94 The C Data Forms Library Page 94